例:
templateclass Base { public: Base(); friend class T; };
现在这不起作用......有没有办法做到这一点?
我实际上是想制作一个像这样的通用类封口机:
class ClassSealer { private: friend class Sealed; ClassSealer() {} }; class Sealed : private virtual ClassSealer { // ... }; class FailsToDerive : public Sealed { // Cannot be instantiated };
我在这个网站上找到了这个例子,但我找不到它...(这里)
我知道还有其他方法可以做到这一点但是现在我很好奇你是否真的能做到这样的事情.
即使某些版本的VisualStudio允许,它也会在标准中明确禁止.
C++标准7.1.5.3详细说明的类型说明符,第2段
3.4.4描述了如何在详细类型说明符中对标识符进行名称查找.如果标识符解析为类名或枚举名,则elaborated-type-specifier将它引入声明,就像simple-type-specifier引入其类型名一样.如果标识符解析为typedef-name或模板类型参数,则elaborated-type-specifier的格式不正确.[注意:这意味着,在具有模板类型参数T的类模板中,声明 友元类T ; 是不正确的.]
我认为上面的代码是一个密封(禁止扩展)类的模式.还有另一个解决方案,它不会真正阻止扩展,但会标记从类中不加扩展.如ADOBE源库中所示:
namespace adobe { namespace implementation { templateclass final { protected: final() {} }; }} #define ADOBE_FINAL( X ) private virtual adobe::implementation::final
用法:
class Sealed : ADOBE_FINAL( Sealed ) {//... };
如果你真的强迫它,它允许扩展:
class SealBreaker : public Sealed, ADOBE_FINAL( Sealed ) { public: SealBreaker() : adobe::implementation::final(), Sealed() {} };
它会限制用户误做.
编辑:
即将推出的C++ 11标准允许您使用稍微不同的语法与类型参数建立联系:
templateclass A { // friend class T; // still incorrect: elaborate type specifier friend T; // correct: simple specifier, note lack of "class" };
我找到了一个简单的技巧来将模板参数声明为朋友:
template < typename T> struct type_wrapper { typedef T type; }; template < typename T> class foo { friend class type_wrapper < T>::type }; // type_wrapper< T>::type == T
但是我不知道这有助于定义类封口机的替代版本.