代码1:
template <class T>
class cat{
public:
T a;
void show(){
cout << a ;
}
};
代码2:
template <class T>
class dog{
public:
T a;
template <class U> // making show function template
void show(){
cout << a ;
}
};
所以cat::show()
是模板类的成员函数
dog::show()
是模板类的成员函数模板。
问题:
1)类模板猫和狗之间有什么区别,而不是当我调用成员函数show时,我必须明确指定U作为狗模板类的例子吗?
2)编译器是否处理它们。例如cat :: show()在我使用它之前不会被编译。我想对于dog :: show();同样的事情。那么我有什么遗失吗?
答案 0 :(得分:1)
这两个只与两个自由函数foo
相关的方式相关:
void foo() {};
template <typename T>
void foo() {}
作为模板类的成员,两者都将根据需要实例化隐式实例化。另一方面,如果显式实例化模板类,则非模板函数将由编译器生成,但模板成员函数不会生成。
除此之外,通常的警告:模板函数只匹配确切的类型,而非模板函数将允许隐式转换:
template <typename T>
struct tmpl {
void foo( T, T ) {}
template <typename U>
void bar( U, U ) {}
};
tmpl<int> t;
t.foo( 5, 1. ); // fine, will convert 1. from double to int
t.bar( 5, 1. ); // error
模板化和非模板化函数之间的所有其他差异。
我真正不理解的是为什么这让你如此困惑。您似乎正在考虑 instantiation 作为函数的唯一属性,而不是。真是困扰你的是什么?为什么你认为模板和非模板函数是相同的?
特别是,我觉得你在实施细节上浪费了太多精力。在大多数情况下,是否实例化模板类的一个或所有成员函数并不会真正影响程序的语义,如果程序需要成员函数,则编译器将为其生成代码,如果你的程序不需要它,它是否生成代码没有区别(考虑到链接器可以删除任何符号,成员函数从未生成或链接器删除它的区别是什么?)