将类模板声明为朋友

时间:2011-10-26 08:23:31

标签: c++ templates friend

由于某些原因,我想写这样的代码:

template<class T>
class C : public T
{
friend class T;
};

我认为代码很清楚。我希望有一个类模板,它定义一个派生自传递给它的类的类作为模板参数,并且为了使事情变得更复杂,我想将基类定义为派生类的朋友。 MSVC编译器的代码似乎没问题,但GNU C ++编译器抱怨很多。我该怎么做才能拥有所需的功能?

1 个答案:

答案 0 :(得分:6)

虽然它在MSVC中有效,但它是不正确的,并且无效C ++。 C ++ 03标准说明了这一点(7.1.5.3§2):

  

3.4.4描述了如何在详细类型说明符中对标识符进行名称查找。如果标识符解析为类名   或enum-name,精心设计的类型说明符将其引入   声明与简单类型说明符引入它的方式相同   键入名称。如果标识符解析为typedef名称或模板   type-parameter,elaborated-type-specifier是不正确的。 [注意:   这意味着,在具有模板的类模板中   type-parameter T,声明

       friend class T;
     

是不正确的。如果名称查找没有找到声明   名称,详细类型说明符是不正确的,除非它是   简单形式类密钥标识符,在这种情况下标识符是   如3.3.1所述声明。

出于同样的原因,您也无法执行friend class std::string;之类的操作,但您必须使用模板参数与std::basic_string建立联系。

然而,新的C ++ 11规范允许声明朋友的新语法,这就是(N3242的11.3§3):

friend <typename-specifier>;

这个新语法允许你做你想做的事情(我不知道MSVC是否支持这个):

template<typename T>
class C : public T
{
    friend T;
};