简体   繁体   中英

Overload operator<< for template class

I am having problem with overloading operator<< for a template class. I am using Visual Studio 2010, and here is my code.

#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

In main I just have

#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 is just a wrapper of int with some special functionality I need.

However, when I compile the above code, I got error C2679, which says binary '<<' : no operator found which takes a right-hand operand of type 'Polyff::FiniteField<T,n>' (or there is no acceptable conversion)

I have also tried to remove the parameters in the friend declaration so the code becomes:

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

But this produce another error: C2785: 'std::ostream &Polyff::operator <<(std::ostream &,const Polyff::FiniteField<T,n> &)' and '<Unknown>' have different return types

so I am wondering how should I change the code so it compiles and why? Thanks!

------------------------- edited on 2012.12.31 ---------------------------

The code compiles with g++ now. Here is the github repository.

This seem to work as expected:

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;  
}

I just replaced the reference by the pointer of your object in the template arguments, since a pointer to a global object (static or not) is an information known at compile-time (or at least link time). I am not aware of the language accepting references.

Note that in this example, 0 will be printed because it corresponds to the default construction of _val .

I tried to compile your code on my Visual C++ 2010. I got the same error as you did.

There are actually two things that Visual did not like in your code:

  1. N is not a compile time constant (which is right, no?).
  2. The problem is then to take the reference of a compile time constant. So, you should replace "T& n" by "T n" in all your template arguments.

That made the job for me!

您应该使用普通变量( T n而不是T& n )替换引用。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM