Top > C++の文法 > テンプレートクラスの演算子の多重定義

以下の投稿に返信 全 5件

Re: テンプレートクラスの演算子の多重定義   by オーバーロード 2007年3月5日 22:55

 
おぉ、ありがとうございます。
&の引数はミスでした^^;下の通りに<>にしたら通りました。
bccなのですが<T>にするとコンパイルできませんでした。(class Aだけなら通る)
後に定義したものがメンバ変数にアクセスできないのでおそらくBのtemplate関数に対して
friend宣言が効いてないのだと思います。operator + <>と書いてあるものが見当たらなかったのでかなり助かりましたm(__)m


Re: テンプレートクラスの演算子の多重定義   by Gimite 2007年3月2日 11:13

 
ちょっと調べてみたんですが、C++の仕様書のサンプルをみた感じだと
> ・この場合のfriend宣言は operator + <> と書くのが正しいらしい。
というのは嘘で、これはoperator + <T>でいいっぽいです。実際BCCではoperator + <T>でもコンパイル通りますね。

gccでoperator + <T>にすると謎のエラーが出たんですが、これはgccのバグかな…。


Re: テンプレートクラスの演算子の多重定義   by Gimite 2007年2月28日 10:11

 
こんな感じにしたらコンパイル通りました。

template<class T>class A;
template<class T>class B;
template<class T>A<T> operator +(A<T>,const A<T>&);
template<class T>B<T> operator +(B<T>,const B<T>&);

template<class T>class A{
  private: T na;
  public:  A(T a):na(a){};
  A<T>&       operator =(A<T> a){na=a.na;return *this;};
  friend A<T> operator + <>(A<T>,const A<T>&);
};
template<class T>class B{
  private: T nb;
  public:  B(T b):nb(b){};
  B<T>&       operator = (B<T> b){nb=b.nb;return *this;};
  friend B<T> operator + <>(B<T>,const B<T>&);
};

template<class T>A<T> operator +(A<T> a1,const A<T>& a2){a1.na=a1.na+a2.na;return a1;}
template<class T>B<T> operator +(B<T> b1,const B<T>& b2){b1.nb=b1.nb+b2.nb;return b1;}

int main()
{
  A<int> a(1);
  B<int> b(2);
  a=a+a;
  b=b+b;
  return 0;
}

ポイントは
・もとの宣言では引数が (B<T>,const B<T>&) となってるのにfriend宣言では (B<T>&,const B<T>&) となっていて、引数の型が一致していなかった。
・この場合のfriend宣言は operator + <> と書くのが正しいらしい。
というところですね…。こういうfriend宣言ははじめて見たので、何故 operator + <> なのかはよく分かりません(汗)。

なんで(全く同じ書き方なのに)Aの方はエラーにならずにBの方だけエラーになったのかは謎です…。BCCのバグだと思います。gccだとAの方だけでもエラーになりました。


Re: テンプレートクラスの演算子の多重定義   by オーバーロード 2007年2月27日 18:44

 
例えば、
template<class T>class A;
template<class T>class B;
template<class T>A<T> operator +(A<T>,const A<T>&);
template<class T>B<T> operator +(B<T>,const B<T>&);

template<class T>class A{
private: T na;
public:  A(T a):na(a){};
A<T>&       operator =(A<T> a){na=a.na;return *this;};
friend A<T> operator + <T>(A<T>&,const A<T>&);
};
template<class T>class B{
private: T nb;
public:  B(T b):nb(b){};
B<T>&       operator = (B<T> b){nb=b.nb;return *this;};
friend B<T> operator + <T>(B<T>&,const B<T>&);
};

template<class T>A<T> operator +(A<T> a1,const A<T>& a2){a1.na=a1.na+a2.na;return a1;}
template<class T>B<T> operator +(B<T> b1,const B<T>& b2){b1.nb=b1.nb+b2.nb;return b1;}

int main()
{
A<int> a(1);
B<int> b(2);
a=a+a;
b=b+b;
return 0;
}
の様にした時にクラスBのメンバ変数(のみ)にアクセスできません。
実際演算子+の場合は+=を使って書くので問題ないのですがostreamの<<などの時に困ってしまいます。


テンプレートクラスの演算子の多重定義   by オーバーロード 2007年2月27日 17:04

 
テンプレートクラスの演算子(+,-,*,/など)のfriendを用いるようなものに関して多重定義する際に、
同じようなテンプレートクラスを更に定義し同じ演算子の多重定義をすると2つ目以降の演算子が
定義できないのですがこの様な場合はどう対処すればよいのでしょうか。


  パスワード:   

Top > C++の文法 > テンプレートクラスの演算子の多重定義