クラステンプレートがありFoo<T>
ます。
Bar
2つのsを取りFoo
、を返す非メンバー関数を実装したいと思いますFoo
。発信者が書くよりもBar
自然になるので、私は非会員になりたいです。計算が簡単で頻繁なので、私もなりたいです。Bar(f1, f2)
f1.Bar(f2)
Bar
inline
template <typename T>
inline Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs) {
...
}
秘訣は、のプライベートデータBar
にアクセスする必要があることです。Foo
プライベートデータへのアクセサーを持たない方がいいです。プライベートデータをユーザーに公開する正当な理由はありません。Bar
だから私はの友達を作りたいですFoo
。
template <typename T>
class Foo {
...
private:
T w, x, y, z;
friend Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs);
};
ここで私は問題にぶつかります。コンパイラは文句を言います:
フレンド宣言が関数テンプレートの特殊化を参照している場合、インライン指定子は使用できません。
このルールは標準によって課されていますか、それともMSVC ++に固有ですか?
これが私が試したことです:
const
Bar
public member関数を作成してから、単に。を返す非メンバーバージョンを宣言しますlhs.Bar(rhs)
。これは最もハッキーな解決策のようです。inline
コンパイラがヒントに関係なくインライン化を決定することを知って、ヒントを削除します。次に、これは単一定義規則に違反しますか?関数テンプレートであるため、ヘッダーファイルで定義する必要があります。ダミーのテンプレートタイプを使用してメンバー関数を宣言します。
template <typename T> class Foo { ... private: T w, x, y, z; // Note that this declaration doesn't actually use Dummy. It's just there to // satisfy the compiler. template <typename Dummy> friend Foo<T> Bar(const Foo<T> &lhs, const Foo<T> &rhs); };
なぜそれが機能するのか完全にはわかりませんが、コンパイラーは満足しています。
より良い解決策はありますか?