I have the following code:
#include <iostream>
#include <stdio.h>
using namespace std;
template <class F>
struct CMPLX {
F Re, Im;
struct _printnice {
F Re, Im;
string sep;
_printnice(const F& Re, const F& Im, const string& sep) : Re(Re), Im(Im), sep(sep) {}
};
CMPLX <F> (F Re, F Im) : Re(Re), Im(Im) {}
_printnice PrintNice(const string& sep="\t"){
return _printnice(Re, Im, sep);
}
};
template<class F>
ostream& operator << (ostream& os, const CMPLX<F> c){
cout << c.Re << " + " << c.Im << "i";
}
template<class F>
ostream& operator << (ostream& os, const CMPLX<F> :: _printnice p){
cout << p.Re << p.sep << p.Im;
}
int main(){
CMPLX<float> c(2.0,1.0);
cout << c << endl;
cout << c.PrintNice() << endl;
}
I introduce a sub-struct _printnice in order to overload the operator << and have differently-formatted output of my CMPLX class. However, this throws an error
expected unqualified-id before ‘p’ and I don’t know how to solve this (my knowledge on templates is very limited).
I try to change the 2nd definition of << to the following which works, but I have to specify the type, which is frowned-upon:
ostream& operator << (ostream& os, const CMPLX <float> :: _printnice p){
cout << p.Re << p.sep << p.Im;
}
There are two issues with your approach. The first is that
_printniceis a dependent name and as such you need to add an extratypename. If that were fixed you would end up with:The problem with this code, as Dietmar pointed out in a previous answer, is that
Fis in a non deducible context, and this will fail.One simple solution is to define the operator inside the scope of the
_printnicecode, where thetypename:Inside the definition of
_printnice, the type is known to be a type and thus thetypenameis no longer required. The overloadedoperator<<will be found by Argument Dependent Lookup, and because it refers to this particular instantiation of the type, there is no template arguments to deduce.