1

代码 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(); 也是一样的。那么我在这里缺少什么吗?

4

1 回答 1

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

以及模板化和非模板化函数之间的所有其他差异。


我真的不明白为什么这会让你如此困惑。您似乎将实例化视为函数的唯一属性,但事实并非如此。真正困扰你的是什么?为什么你认为模板和非模板函数是一样的?

特别是,我觉得您在实现细节上浪费了太多精力。在大多数情况下,一个模板类的一个或所有成员函数是否被实例化并不会真正影响你程序的语义,如果你的程序需要该成员函数,那么编译器会为它生成代码,如果你的程序不需要它,它是否生成代码没有区别(考虑链接器可以删除任何符号,成员函数从未生成或被链接器删除有什么区别?)

于 2012-06-30T01:55:35.267 回答