C++模板的特例化编译为多重定义问题
生活随笔
收集整理的这篇文章主要介绍了
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++模板的特例化编译为多重定义问题的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: JavaScript正则表达式
- 下一篇: nginx访问控制:如何通过map来控制