由于某些原因,我想写这样的代码:
template<class T>
class C : public T
{
friend class T;
};
我认为代码很清楚。我希望有一个类模板,它定义一个派生自传递给它的类的类作为模板参数,并且为了使事情变得更复杂,我想将基类定义为派生类的朋友。 MSVC编译器的代码似乎没问题,但GNU C ++编译器抱怨很多。我该怎么做才能拥有所需的功能?
答案 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;
};