template classのfriend関数をクラス内部で実装する
テンプレートクラスを作成し、その演算子などを非メンバ関数で定義する場合
往々にして、friend関数にする場合が多いと思います
これが厄介で、まずテンプレートクラスの前方宣言をします
その後にテンプレート関数として目的のfriend関数を前方宣言します
次にテンプレートクラス内部で目的の関数をfriend関数宣言をします
最後にテンプレートクラス外部で実装を書きます
friend関数をいたるところに書いてやる必要があります
// classの前方宣言 template <typename T> class Obj; // friend関数の前方宣言 template <typename T> std::ostream& operator<<(std::ostream&,const Obj<T>& t); // class実装 template <typename T> class Obj { private: T t_; public: Obj(T t) : t_(t) { } Obj()=default; // friend関数指定 // template<typename U> // friend std::ostream& operator<< (std::ostream&,const Obj<U>&); // ベタ書き friend std::ostream& operator<< <T>(std::ostream&,const Obj<T>&); // すこし簡略化 }; // friend関数の実装 template <typename T> std::ostream& operator<< (std::ostream& o,const Obj<T>& t) { return o << t.t_; }
うわぁ・・・ めんどくさいですね
と、思っていたのですが、もっとスマートに書く方法がありました
template <typename T> class Obj { private: T t_; public: Obj(T t) : t_(t) { } Obj()=default; //friend関数指定も実装も全部まとめて書ける。前方宣言もいらない friend std::ostream& operator<< (std::ostream& o,const Obj& t) { return o << t.t_; } };
http://melpon.org/wandbox/permlink/vvT6OT7PsGGAShBW
こんなふうに書けるのは知りませんでした
これで関数前言をばら撒かなくてよくなりました!
やったね!