VisualStudio の一部のバージョンで許可されていても、標準では明示的に禁止されています。
C++ 標準 7.1.5.3 詳細な型指定子、段落 2
3.4.4 では、詳細型指定子の識別子の名前検索がどのように進行するかについて説明します。識別子がクラス名または列挙名に解決される場合、単純型指定子がその型名を導入するのと同じ方法で、詳細型指定子はそれを宣言に導入します。識別子が typedef-name またはテンプレートの型パラメーターに解決される場合、詳細な型指定子の形式が正しくありません。[注: これは、テンプレート型パラメーター T を持つクラス テンプレート内で、宣言 のフレンド クラス Tを意味します。は不正です。]
上記のコードは、クラスを封印する (拡張を禁止する) パターンとして認識しています。拡張機能を実際にブロックするのではなく、クラスから誤って拡張することを示す別の解決策があります。ADOBE Source Libraryに見られるように:
namespace adobe { namespace implementation {
template <class T>
class final
{
protected:
final() {}
};
}}
#define ADOBE_FINAL( X ) private virtual adobe::implementation::final<T>
使用法で:
class Sealed : ADOBE_FINAL( Sealed )
{//...
};
あなたが本当にそれを強制した場合、それは拡張を許可しますが:
class SealBreaker : public Sealed, ADOBE_FINAL( Sealed )
{
public:
SealBreaker() : adobe::implementation::final<Sealed>(), Sealed() {}
};
ユーザーが誤ってそれを行うのを制限します。
編集:
次の C++11 標準では、わずかに異なる構文で型引数と友達になることができます。
template <typename T>
class A {
// friend class T; // still incorrect: elaborate type specifier
friend T; // correct: simple specifier, note lack of "class"
};