将类模板声明为友元

declare class template as friend

本文关键字:友元 声明      更新时间:2023-10-16

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

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

我认为代码很清楚。我想有一个类模板,它定义了一个从传递给它的类作为模板参数派生的类,为了使事情变得更复杂,我想将基类定义为派生类的朋友。代码似乎可以与MSVC编译器,但GNU c++编译器抱怨很多。我应该做些什么来实现所需的功能?

它是病态的,虽然在MSVC中工作,但在c++中是无效的。c++ 03标准是这样说的(7.1.5.3§2):

3.4.4描述了详细类型说明符中标识符的名称查找过程。如果标识符解析为类名或enum-name,精心设计的类型说明符将其引入声明的方式与简单类型说明符引入其类型名称。如果标识符解析为类型定义名称或模板类型参数,详细的类型说明符是病态的。【注:这意味着,在类模板中使用模板类型参数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;
};