У меня проблема с перегрузкой оператора<< для шаблона класса. Я использую 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;
}
где 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
Кажется, это работает как ожидалось:
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
,
Вы должны просто заменить ссылку простой переменной (T n
вместо T& n
).
Я пытался скомпилировать ваш код на моем Visual C ++ 2010. Я получил ту же ошибку, что и вы.
На самом деле Visual Studio не понравилось в вашем коде:
Это сделало работу для меня!