Оператор перегрузки & lt; & lt; для шаблона класса

У меня проблема с перегрузкой оператора<< для шаблона класса. Я использую 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

6

Решение

Кажется, это работает как ожидалось:

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,

1

Другие решения

Вы должны просто заменить ссылку простой переменной (T n вместо T& n).

1

Я пытался скомпилировать ваш код на моем Visual C ++ 2010. Я получил ту же ошибку, что и вы.

На самом деле Visual Studio не понравилось в вашем коде:

  1. N не является постоянной времени компиляции (что верно, нет?).
  2. Проблема состоит в том, чтобы взять ссылку на постоянную времени компиляции. Итак, вы должны заменить «T& n «от» T n «во всех аргументах шаблона.

Это сделало работу для меня!

0
По вопросам рекламы [email protected]