欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

C++模板的特例化编译为多重定义问题

发布时间:2025/5/22 c/c++ 115 豆豆
生活随笔 收集整理的这篇文章主要介绍了 C++模板的特例化编译为多重定义问题 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

    之前遇到了一些关于模板特例化的问题,自己总结一下。

    模板的特例化是C++新标准的一个特点,可以自定义某些模板的实现,比如在比较函数compare可以使用less<T>标准库模板比较string、int、char、指针等类型,但如果有const char*类型且比较字符串的字典大小时,就与之前的比较方式不同了:

#ifndef A_H #define A_H#include <iostream> #include <cstring> using std::less; template <typename T> int compare(const T v1,const T v2)  {if (less<T>()(v1,v2)) {return -1;}else if (less<T>()(v2,v1)){return 1;}else{return 0;} }template <> inline int compare(const char *const a,const char *const b)  {return strcmp(a,b); }#endif #include "a.h" using std::cout; using std::endl;int main() {cout << compare(1,2) << endl;  cout << compare("123","asd") << endl;  return 0; }

    现在看上去没什么问题,并且只有这两个文件编译通过且正常运行,如果多了一个包含a.h的文件a.cpp:

#include "a.h"

    这里只有一句,但包含了a.h文件表示将其模板函数的定义包含,且特例化的函数类似一个普通函数,则a.cpp、main.cpp包含多个相同函数的定义,因此在链接时有重定义问题。

    解决方法:

    使用内联inline声明特例化的模板,则某些函数的定义可以在多个文件包含(一些函数的实现可能不支持内联): 

template <> inline int compare(const char *a,const char *b)  {return strcmp(a,b); }

    另外一个是使用一个文件包含该头文件,让所有链接的文件只有一个特例化定义

    第三个是定义普通同名函数,通过重载调用非模板函数(在参数匹配级别相同时,非模板重载函数优先调用)

// a.h #ifndef A_H #define A_H#include <iostream> #include <cstring> using std::less; template <typename T> int compare(const T v1,const T v2) {if (less<T>()(v1,v2)){return -1;}else if (less<T>()(v2,v1)){return 1;}else{return 0;} }int compare(const char *a,const char *b) ;// a.cpp #include "a.h"int compare(const char *a, const char *b) {std::cout << "const char*"<<std::endl;return strcmp(a,b); } // main.cpp 相同

    如果有其他的方法请大家一起交流

转载于:https://blog.51cto.com/zmh009/1883801

总结

以上是生活随笔为你收集整理的C++模板的特例化编译为多重定义问题的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。