次の 2 つのテンプレート クラスがあるとします。
template <class _A>
class First
{
private:
int a;
};
template <class _B>
class Second
{
private:
int b;
};
多対多の友情でそれらをリンクするにはどうすればよいですか。たとえば、Second のパラメーター オブジェクトの b を出力するメソッドを First に追加します。
私の質問は明確ですか?
次の 2 つのテンプレート クラスがあるとします。
template <class _A>
class First
{
private:
int a;
};
template <class _B>
class Second
{
private:
int b;
};
多対多の友情でそれらをリンクするにはどうすればよいですか。たとえば、Second のパラメーター オブジェクトの b を出力するメソッドを First に追加します。
私の質問は明確ですか?
template <typename T>
class First {
int a;
template<typename> friend class Second;
};
template <typename T>
class Second
{
int b;
template<typename> friend class First;
};
これにより、 everyFirst<T>
が every の内部にアクセスできるようになりますSecond<U>
。さて、これは技術的な解決策ですが、循環依存関係を持ち、他のクラスのインスタンス化に対して内部を開く設計が、特定の問題に対する最善の解決策であるかどうかを検討することをお勧めします。
First<int>
ところで、へのアクセスのみを許可したい場合Second<int>
( ではなくSecond<double>
) は、次のように実行できます。
template <typename> class Second;
template <typename T>
class First {
int a;
friend class Second<T>; // only befriend the same instantiation
};
template <typename T>
class Second {
int b;
friend class First<T>;
};
この 2 番目のバージョンでSecond
は、特定のインスタンス化をフレンドシップする前にテンプレートの前方宣言が必要ですが、これにより、クラスの内部へのアクセスを特定のインスタンス化のみに許可できます。
各クラスの宣言から始めることができます:
template< typename T > class First;
template< typename T > class Second;
これで、両方のクラスが定義でもう一方のクラスを認識します。必要に応じて、そこで友達として宣言できます。
template< typename T > class First
{
template< typename U> friend class Second;
};
そして逆も同じ。
お互いの詳細を確認する必要がある場合は、クラス定義の下に関数本体を実装することもできます。つまり、「前方宣言」コピーを使用できません。
保護を理解していると仮定すると、テンプレートの前方宣言を発行します。
#include <iostream>
template <class _B> class Second; // Forward declare
template <class _A>
class First
{
public:
template<class _B>
void print(const Second<_B>& b)
{
std::cout << b.b << std::endl;
}
int a;
};
template <class _B>
class Second
{
public:
int b;
};
void testIt()
{
Second<double> sd;
First<int >fi;
fi.print<double>(sd);
}