Overload operator << for class template

I have a problem with the overload 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 

Basically i just

 #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 an int wrapper with some special functionality that I need.

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

I also tried removing the parameters in the friend declaration so that the code becomes:

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

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

so I wonder how can I change the code so that it compiles and why? Thanks!

------------------------- revision on 2012.12.31 ----------------- --- -------

Now the code compiles with g ++. Here is the github repository.

+6
source share
3 answers

This seems 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 to the pointer to your object in the template arguments, because the pointer to the global object (static or not) is information known at compile time (or at least link time). I do not know the language that accepts links.

Note that in this example, 0 will be printed because it matches the default _val .

+1
source

You should simply replace the reference with a simple variable ( T n instead of T& n ).

+1
source

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

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

  • N is not a compile-time constant (what's right, no?).
  • The problem is to take a reference to the compile-time constant. Thus, you must replace ā€œT & nā€ with ā€œT nā€ in all template arguments.

It did the job for me!

0
source

All Articles