将类模板声明为朋友

mod*_*baf 4 c++ templates friend

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

template<class T>
class C : public T
{
friend class T;
};
Run Code Online (Sandbox Code Playgroud)

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

rek*_*o_t 6

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

3.4.4描述了如何在详细类型说明符中对标识符进行名称查找.如果标识符解析为类名或枚举名,则elaborated-type-specifier将它引入声明,就像simple-type-specifier引入其类型名一样.如果标识符解析为typedef-name或模板类型参数,则elaborated-type-specifier的格式不正确.[注意:这意味着,在具有模板类型参数T的类模板中,声明

       friend class T;
Run Code Online (Sandbox Code Playgroud)

是不正确的.如果名称查找没有找到名称的声明,则elaborated-type-specifier是格式错误的,除非它是简单形式的类 - 密钥标识符,在这种情况下,标识符的声明如3.3.1中所述.

出于同样的原因,你不能做friend class std::string;任何事情,但你必须与std::basic_string模板参数成为朋友.

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

friend <typename-specifier>;
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>
class C : public T
{
    friend T;
};
Run Code Online (Sandbox Code Playgroud)