函数指针的模板自动推导问题及头文件引用疑问
C++模板变量相关问题解答
一、调用p(3)必须显式指定模板参数的原因
你定义的p是模板变量,而非函数模板。第一个例子里的函数模板f,调用时编译器能通过传入的实参直接推导模板参数T;但模板变量是另一回事——每个T都会对应一个独立的指针变量实例(比如p<int>、p<double>),这些是完全不同的变量。
当你写p(3)时,编译器找不到任何上下文来推导模板变量的T值,它不知道你要调用的是哪个T对应的p实例。模板参数推导只支持函数模板、类模板构造函数等场景,模板变量的实例化没法通过函数调用的实参来推导,所以必须显式指定模板参数,比如写成p<int>(3)才能正常编译。
二、模板变量放在头文件被多文件包含的问题
不会引发重复定义错误。因为模板本身不是具体的实体,只有当模板被实例化(比如某个编译单元里用到了p<int>)时,才会生成具体的变量实体。
C++的ODR(单定义规则)允许模板在多个翻译单元中存在定义,只要各个翻译单元中模板的定义完全一致,链接器会自动合并不同翻译单元中实例化出的同类型模板实体(比如多个文件里都用到的p<int>)。
需要注意:如果后续对这个模板变量做显式特化,那特化的定义不能直接放在头文件(除非标记为inline),否则会触发重复定义错误;但普通的模板变量定义放在头文件是安全的。
内容的提问来源于stack exchange,提问作者Bubaya
相关产品推荐
相关产品推荐

