我今天很开心。这是第 7 题 n00b:
当您尝试重载模板函数时,显式特化和普通函数有什么区别?
什么情况下适合使用显式特化?我不太明白:
#include <iostream>
template <typename s> void test(s var1);
template <> void test<int>(int var1);
int main(){
test(1);
test(1.1);
test("hello!!");
return 0;
}
template <typename s> void test(s var1){
std::cout << var1 << std::endl;
}
template <> void test<int>(int var1){
std::cout << "int " << var1 << std::endl;
}
反对:
#include <iostream>
template <typename s> void test(s var1);
void test(int var1);
int main(){
test(1);
test(1.1);
test("hello!!");
return 0;
}
template <typename s> void test(s var1){
std::cout << var1 << std::endl;
}
void test(int var1){
std::cout << "int " << var1 << std::endl;
}
最佳答案
除了当编译器为函数调用寻找匹配的签名类型时,它会首先选择一个非模板之外,显式专门化的模板函数和非模板常规函数之间确实没有区别在尝试实例化可能满足所需签名匹配的任何可用模板函数之前,匹配所需签名的函数。
如果你要在头文件中声明和定义一个不是模板函数的函数,你必须将该函数声明为inline
。这是因为模板函数在实际实例化之前不是与代码模块链接的实际函数。然后,链接器在编译代码模块后丢弃该实例化。如果链接器不这样做,那么每次 .cpp 文件包含头文件时,链接器都会提示函数的重复定义。在非模板函数上使用 inline
关键字在编译器级别具有类似的效果,因为只要在 .cpp 文件中使用该函数,编译器就会将该函数调用替换为头文件中 inline
函数的函数代码,并避免了函数调用的开销以及相关的堆栈事件记录设置和清理。因此,链接器不会提示函数的重复定义。
关于c++ - 重载模板函数时显式特化和常规函数之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5986935/