10

テンプレート化されたクラスの特定の特殊化のみをフレンドシップするための構文はありますか、それともすべての特殊化を次のようなものとフレンドシップする必要がありますか?

template<class FooType> friend class Bar;

存在する場合、次のようなものを探します。

template<class FooType> friend class Bar<FooType const>;

スペシャライゼーションには、デフォルトでお互いの友達ではないため、独自の「友達になれる」アイデンティティがあるようです。たとえば、getFoo()これはプライベートであるため、const 特殊化から派生した非 const ケースでは呼び出すことができません。

template<class FooType> class Bar;

template<class FooType>
class Bar<FooType const> {
public:
    Bar (std::string name) : _foo (name) { }
    FooType const * operator->() const
        { return &getFoo(); }
private:
    FooType const & getFoo() const
        { return _foo; }
private:
    FooType _foo;
};

template<class FooType>
class Bar : public Bar<FooType const> {
public:
    Bar (std::string name) : Bar<FooType const> (name) { }
    FooType * operator->()
        { return &getFoo(); }
private:
    FooType & getFoo()
        { return const_cast<FooType &>(Bar<FooType const>::getFoo()); }
};

template<class FooType> friend Bar;const 特殊化に追加する必要があります。

(余談ですが、のタグの説明はちょっとおかしいです。)

4

1 に答える 1

11

あなたは探している

friend Bar<FooType const>;

これは、 s を宣言できる2 つの方法のうちの 1 つです。friend最初の構文は、クラスをフレンドとして宣言します。

friend Type;

whereTypeは単純なタイプBar(テンプレートではない) にすることも、クラス テンプレートの特定のインスタンス化にすることもできます (例: ) Baz<int>intもちろん、囲んでいるクラス テンプレートからのテンプレート パラメーターまたは好きなものにすることもできます。ポイントは、フレンドステータスが付与された単体タイプです。

2 番目の構文は、クラス テンプレートをフレンドとして宣言します。

template< ... > friend class ClassTemplate;

ここで、...は のテンプレート パラメータ宣言ですClassTemplate。ご覧のとおり、テンプレート パラメーター リストのみを指定する必要がありますが、リストはどこにも使用されていません。両方の構文を組み合わせることはできません。クラス テンプレートを「部分的にフレンド」にする方法や、SFINAE/ を使用してenable_if特定のフレンド宣言を有効または無効にする方法はありません。実際、テンプレートパラメータに名前を追加することはあまり意味がありません。上記のように書くだけです

template< class > friend class Bar;

追加FooTypeしても、ここでは何も価値がありません。

于 2013-10-23T16:22:45.353 に答える