0
struct ABC {};

template<typename T>
class DEF
{
   void f0(typename T::ab) {} //ERROR
   void f1() {typename T::ab var;} //Fine
};

DEF<ABC> obj;

我想如果我不使用类模板的特定成员函数,它永远不会被编译器构造。因此,正如预期f1()的那样,即使代码编译得很好,因为obj从不使用它。为什么存在f0()导致编译错误?我也不用那个。

{MinGW g++ 4.7.2,Windows 7}

4

3 回答 3

4

每个成员函数声明都是整个类定义的一个组成部分。同时,成员函数定义是一个完全独立的实体,它不是类定义的一部分。

当您实例化某个专门模板类的对象时,您正在实例化该类的整个定义,即您正在“使用”该类的整个定义,这反过来意味着您也在“使用”所有成员声明。

下面是在您的情况下变成类定义的部分,一旦模板被专门化

template<typename T>
class DEF
{
   void f0(typename T::ab);
   void f1();
};

T为了使类定义可用,即为了能够声明 ,上述所有内容必须对给定的值有效DEF<ABC> obj;

同时定义

template<typename T> void DEF<T>::f1() 
{
  typename T::ab var;
}

是一个独立的模板。仅当您使用f1.

于 2013-06-04T16:56:49.510 回答
2

编译器至少需要一个有效的函数原型,然后确定它是否被使用(然后随后编译主体)。

于 2013-06-04T16:47:40.867 回答
2

这是因为惰性实例化。当你这样做DEF<ABC> obj。编译器将查看类 DEF 的原型/定义。因此void f0(typename T::ab)失败,因为 ab 不存在并且您收到编译错误。

您没有收到编译器错误的void f1(){typename T::ab var}原因是因为它从未被实例化。如果你这样做obj.f1()了,你会看到它会报错与与 DEF::f0 关联的消息相同的消息。

于 2013-06-04T16:53:59.113 回答