6

私は最近、演算子のオーバーロード/テンプレートの能力を測定しようとしていて、小さなテストとして、以下のContainerクラスを作成しました。このコードは正常にコンパイルされ、MSVC 2008(11を表示)で正しく機能しますが、MinGW/GCCとComeauの両方がoperator+過負荷でチョークします。私はMSVCよりもそれらを信頼しているので、自分が間違っていることを理解しようとしています。

コードは次のとおりです。

#include <iostream>

using namespace std;

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
   public: void setobj(T ob);
     T getobj();
      private: T obj;
};

template <typename T>
void Container<T>::setobj(T ob)
{
   obj = ob;
}

template <typename T>
T Container<T>::getobj()
{
   return obj;
}

template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
{
      Container<T> temp;
      temp.obj = lhs.obj + rhs.obj;
      return temp;
}

int main()
{    
    Container<int> a, b;

 a.setobj(5);
    b.setobj(6);

 Container<int> c = a + b;

 cout << c.getobj() << endl;

    return 0;
}

これはComeauが与えるエラーです:

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 27: error: an explicit template argument list is not allowed
          on this declaration
  Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
               ^

1 error detected in the compilation of "ComeauTest.c".

Comeau / MingGWにボールをプレーさせるのに苦労しているので、そこで皆さんに目を向けます。私の脳がC++構文の重みでこれほど溶けてから久しぶりなので、少し恥ずかしい思いをします;)。

編集:最初のComeauダンプにリストされている(無関係な)左辺値エラーを排除しました。

4

5 に答える 5

6

このフォーラム投稿のおかげで解決策を見つけました。基本的に、クラス内で「friend」を使用する前に関数プロトタイプが必要ですが、関数プロトタイプを適切に定義するには、クラスを宣言する必要もあります。したがって、解決策は、(関数とクラスの)2つのプロトタイプ定義を上部に配置することです。次のコードは、3つのコンパイラすべてでコンパイルされます。

#include <iostream>

using namespace std;

//added lines below
template<typename T> class Container;
template<typename T> Container<T> operator+ (Container<T>& lhs, Container<T>& rhs); 

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
      public: void setobj(T ob);
              T getobj();
      private: T obj;
};

template <typename T>
void Container<T>::setobj(T ob)
{
      obj = ob;
}

template <typename T>
T Container<T>::getobj()
{
      return obj;
}

template <typename T>
Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
{
      Container<T> temp;
      temp.obj = lhs.obj + rhs.obj;
      return temp;
}

int main()
{    
    Container<int> a, b;

    a.setobj(5);
    b.setobj(6);

    Container<int> c = a + b;

    cout << c.getobj() << endl;

    return 0;
}
于 2009-06-07T19:44:41.350 に答える
2
template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)

operator+ここでは、一般的なテンプレートに特化したものではなく、新しいテンプレートを宣言しているだけなので、後の「<>」を削除する必要があります。また、少なくともg++フレンド宣言の前にテンプレート宣言を見たいので、の宣言の前に移動する必要がありContainerます。したがって、宣言の次の順序が機能します。

// forward declaration of Container<T>
template <typename T>
class Container;

template <typename T>
Container<T> operator+(Container<T>& lhs, Container<T>& rhs)
{ ... }

template <typename T>
class Container
{
      friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
      ...
};
于 2009-06-07T19:46:05.213 に答える
1

クラスで直接関数を定義する方がよいでしょう。また、パラメータをconst参照として渡す必要があります。

template <typename T>
class Container
{
public:
    friend Container operator+ (Container const & lhs, Container const & rhs)
    {
        // ...
    }
};
于 2009-06-07T20:37:41.880 に答える
1

私はこれをGCCで試してみて、いくつかの変更を加えてコンパイルして実行しました。GCCを満足させるために私がしなければならなかった2つの変更がありました。

1つはフレンドテンプレート関数の宣言でした。これはクラス1とは別の独自のテンプレート宣言であるため、ContainerクラスのTの代わりにUを使用しました。また、operator+の後の<>も削除しました。テンプレートの特殊化を作成していない限り、これらは必要ないと思います。

      template<typename U>
      friend Container<U> operator+ (Container<U>& lhs, Container<U>& rhs);

二、ライン

Container<int>& c = a + b;

一時的なもの(追加の結果)への参照を保存するように要求しているため、GCCで飛行しませんでした。結果を保存する場所があるように、アンパサンドを削除しました。

私はあなたの投稿をちょうど今見ました、それは前方宣言のためにも機能します。とにかく、それらを必要としない代替手段としてこれを投稿すると思います。もちろん、私はGCCでのみテストしました...

于 2009-06-07T19:54:45.133 に答える
0

'operator +'はメンバー関数ではなく、テンプレート化されていません。テンプレート化されたパラメータを受け取るのは、operator+だけです。

 template <typename T>
 Container<T> operator+ (Container<T>& lhs, Container<T>& rhs)
于 2009-06-07T19:47:20.563 に答える