ページ 11

テンプレートクラス内で定義したフレンド関数を外に出したい。

Posted: 2010年5月05日(水) 19:30
by 組木紙織
久々に質問します。

以下のようなテンプレートクラス(抜粋)を作っています。
その中にあるフレンド関数をクラスの外に出したいです。
どのようにすればいいでしょうか?

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

template<typename T>
class vec
{
private:
std::vector<T> obj_;
public:
vec(T a1, T a2);

//ここの関数の実体をクラスの外に出したい。
friend std::ostream & operator<< (std::ostream &stream,const vec<T>& ob)
{
std::vector<T>::const_iterator i=ob.obj_.end();
stream << "(" ;
copy(ob.obj_.begin(),ob.obj_.end()-1,std::ostream_iterator<T>(stream,", "));
stream << *(i-1) <<")";
return stream;
}

};
/***************************************************************************
テンプレートの実体
***************************************************************************/

//コンストラクタ
template<typename T>
vec<T>::vec(T a1, T a2):obj_(2)
{
obj_[0] = a1;
obj_[1] = a2;
}

int main()
{
vec<int> v(1,1);
std::cout << v << std::endl;
}

Re:テンプレートクラス内で定義したフレンド関数を外に出したい。

Posted: 2010年5月05日(水) 21:24
by たかぎ
この話は、不具合を持った処理系が多かったような気もしますが...

以下のようにすればうまくいきませんか?

template<typename T> class vec;

template <typename T>
std::ostream & operator<< (std::ostream &stream,const vec<T>& ob);

template<typename T>
class vec
{
private:
std::vector<T> obj_;
public:
vec(T a1, T a2);

friend std::ostream & operator<< <T>(std::ostream &stream,const vec& ob);

};

//コンストラクタ
template<typename T>
vec<T>::vec(T a1, T a2):obj_(2)
{
obj_[0] = a1;
obj_[1] = a2;
}

template <typename T>
std::ostream & operator<< (std::ostream &stream,const vec<T>& ob)
{
typename std::vector<T>::const_iterator i=ob.obj_.end();
stream << "(" ;
copy(ob.obj_.begin(),ob.obj_.end()-1,std::ostream_iterator<T>(stream,", "));
stream << *(i-1) <<")";
return stream;
}

Re:テンプレートクラス内で定義したフレンド関数を外に出したい。

Posted: 2010年5月05日(水) 21:42
by 組木紙織
私の環境(VS2005)ではうまくいきました。
ありがとうございます。


>この話は、不具合を持った処理系が多かったような気もしますが...
そうなんですか?
この環境では出来ることは知っていたので気にしてなかったです。

さすがにフリーのBCC5.5とかでは問題があると思いますが。

重要な点は
friend std::ostream & operator<< <T>(std::ostream &stream,const vec& ob);

テンプレート引数をつけてfriend宣言することですかね。
忘れないように記録しておきます。

Re:テンプレートクラス内で定義したフレンド関数を外に出したい。

Posted: 2010年5月05日(水) 21:44
by たかぎ
> テンプレート引数をつけてfriend宣言することですかね。

そうですね。
あと、それを可能にするために、先行宣言が必要になることもポイントです。