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++模板的特例化编译为多重定义问题相关推荐
- 函数模板的特例化(专用化)以及类型含有const的特殊情况
一.函数模板特例化: 1 #include <iostream> 2 #include <typeinfo>3 using namespace std;4 5 template ...
- C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板部分特例化
1. 类模板的部分特例化(partial specialization) 类模板的特例化不必为所有模板参数提供实参(可以只指定一部分而非所有模板参数, 或是参数的一部分而非全部特性).类模板的部分特例 ...
- 【深入理解C++】函数模板和类模板的特例化
文章目录 1.函数模板的特例化 1.1 函数模板的全特化 1.2 函数模板不能偏特化 1.3 函数模板.函数模板的全特化.普通函数 2.类模板的特例化 2.1 类模板的全特化 2.2 类模板成员函数的 ...
- 类和函数模板以及特例化
一.函数模板 1.定义 建立一个通用函数,它所用到的数据的类型(包括返回值类型.形参类型.局部变量类型)可以不具体指定,而是用一个虚拟的类型来代替(实际上是用一个标识符来占位),等发生函数调用时再根据 ...
- 【C++模板】类模板的全部特例化和局部特例化(偏特化-partial specialization)
前言 本专栏所有的文章都需要一定的基础知识.在文中对于基础的概念将会一带而过,或者在其他文章有讲,会贴出对应的链接而不再进行赘述. 目录 前言 类模板的Stack实现 类模板的全部特例化(偏特化) 写 ...
- C++模板与泛型编程:模板特例化
文章目录 模板特例化 定义函数模板特例化 函数重载与模板特例化 类模板特例化 类模板部分特例化 特例化成员而不是类 模板特例化 编写单一模板,使之对任何可能的模板实参都是最合适的,都能实例化,这并 ...
- C++:51---重载与模板、模板特例化
一.重载与模板 函数模板可以被另一个模板或一个普通非模板函数重载 如果涉及函数模板,则函数匹配规则会有以下的约束: ①对于一个调用,其候选函数包括所有模板实参推断成功的函数模板实例 ②候选的函数模板总 ...
- C++:19---重载与模板、模板特例化
一.重载与模板 函数模板可以被另一个模板或一个普通非模板函数重载 如果涉及函数模板,则函数匹配规则会有以下的约束: 如果同样好的函数中只有一个是非模板函数,则选择此函数 如果同样好的函数中没有非模板函 ...
- 模板类的特例化(具体化)
模板的基础知识: 模板的实例化 模板并不是真正的函数或类,它仅仅是编译器用来生成函数或类的一张"图纸".模板不会占用内存,最终生成的函数或者类才会占用内存.由模板生成函数或类的过程 ...
最新文章
- 小程序云开发获取手机号完整代码 云函数中网络请求第三方接口
- 懂得了这些才可以说学习Python入门了
- php where 优先,php – 使用WHERE选择所有内容
- 中国肠道大会 | 日程及嘉宾
- Android之如何获取网络类型并判断是否可用
- Java程序员考什么证可以镀金?
- 开课吧python好吗-开课吧9.9元学Python课程适合哪些人?开课吧靠谱吗?
- 解决Ubuntu14.04在外接显示器不能指定问题的最佳分辨率
- 从GCN中学习的信息熵
- 致初级开发的一封信:坚持写代码!
- 详解Paint的setColorFilter(ColorFilter filter)
- Juniper防火墙新手教程8:Juniper防火墙配置的导入及导出
- K8s运行dashboard命令启动报错:no endpoints available for service \kubernetes-dashboard\
- 堆栈的缓冲区溢出进不了系统_一文理解缓冲区溢出
- 基于速度学习机的局部感受野
- ApiCloud重新定义移动应用开发
- BrainOS —最像大脑的AI
- python 闲鱼_闲鱼上哪些商品抢手?Python 分析后告诉你
- docker防止fork炸弹
- Linux自动备份压缩MySQL数据库的实用方法