6

テンプレート クラスの operator<< のオーバーロードに問題があります。私は Visual Studio 2010 を使用しています。これが私のコードです。

#ifndef _FINITEFIELD
#define _FINITEFIELD
#include<iostream>

namespace Polyff{
    template <class T, T& n> class FiniteField;
    template <class T, T& n> std::ostream& operator<< (std::ostream&, const FiniteField<T,n>&);

    template <class T, T& n> class FiniteField {
    public:
            //some other functions
    private:
        friend std::ostream& operator<< <T,n>(std::ostream& out, const FiniteField<T,n>& obj);
        T _val;
    };

    template <class T, T& n>
    std::ostream& operator<< (std::ostream& out, const FiniteField<T,n>& f) {
        return  out<<f._val;
    }
    //some other definitions
}
#endif

主に私はちょうど持っています

#include"FiniteField.h"
#include"Integer.h"
#include<iostream>
using std::cout;
using namespace Polyff;
Integer N(5);

int main () {

    FiniteField<Integer, N> f1;
    cout<< f1;  
}

whereは、必要な特別な機能を備えIntegerた単なるラッパーです。int

ただし、上記のコードをコンパイルすると、エラー C2679 が表示されます。binary '<<' : no operator found which takes a right-hand operand of type 'Polyff::FiniteField<T,n>' (or there is no acceptable conversion)

コードが次のようになるように、フレンド宣言のパラメーターも削除しようとしました。

friend std::ostream& operator<< <> (std::ostream& out, const FiniteField<T,n>& obj);

しかし、これは別のエラーを生成します: C2785:'std::ostream &Polyff::operator <<(std::ostream &,const Polyff::FiniteField<T,n> &)' and '<Unknown>' have different return types

だから、コンパイルできるようにコードをどのように変更すればよいのでしょうか?なぜですか? ありがとう!

------------------------- 2012.12.31 編集 -------------------- -------

コードは g++ でコンパイルされるようになりました。ここに github リポジトリがあります。

4

3 に答える 3

1

これは期待どおりに動作するようです:

namespace Polyff{
  template <class T, T* n> class FiniteField;
  template <class T, T* n> std::ostream& operator<< (std::ostream&, const FiniteField<T,n>&);

  template <class T, T* n> class FiniteField {
  public:
    //some other functions
  private:
    friend std::ostream& operator<< <T,n>(std::ostream& out, const FiniteField<T,n>& obj);
    T _val;
  };

  template <class T, T* n>
  std::ostream& operator<< (std::ostream& out, const FiniteField<T,n>& f) {
    return  out << f._val.n; // I added the field of my Integer class
  }
  //some other definitions
}


struct Integer{
  Integer() : n(0){}
  Integer(int nn) : n(nn){}
  int n;
};

using std::cout;
using namespace Polyff;
Integer N(5);

int main () {
  FiniteField<Integer, &N> f1;
  cout<< f1;  
}

グローバルオブジェクトへのポインタ(静的かどうかに関係なく)はコンパイル時(または少なくともリンク時)に既知の情報であるため、テンプレート引数の参照をオブジェクトのポインタに置き換えました。参照を受け入れる言語を知りません。

この例で0は、 のデフォルトの構造に対応しているため、 が出力されることに注意してください_val

于 2013-02-22T21:23:37.877 に答える
0

Visual C++ 2010 でコードをコンパイルしようとしましたが、同じエラーが発生しました。

Visual があなたのコードで気に入らなかった点が実際には 2 つあります。

  1. N はコンパイル時定数ではありません (どちらが正しいですか?)。
  2. 問題は、コンパイル時定数の参照を取ることです。したがって、すべてのテンプレート引数で「T& n」を「T n」に置き換える必要があります。

それは私のために仕事をしました!

于 2013-01-04T15:39:32.417 に答える
0

参照を単純な変数 (T nの代わりにT& n) に置き換えるだけです。

于 2013-08-07T07:36:31.137 に答える