Я пытаюсь создать класс шаблона, представляющий набор элементов, который перегружает оператор "+" двумя способами: например: someNewSet = setA + setB;
и это: someNewSet = setA + newElement;
(Я знаю, что плохая практика использовать его так, но, пожалуйста, несите меня.)
Тем не менее, я продолжаю сталкиваться с проблемой с последним, что может быть показано в этом примере:
foo.h:
template<typename T>
class Foo {
private:
T bar;
public:
Foo(T arg);
template<typename TT> friend Foo<TT> operator + (Foo<TT>& a, Foo<TT>& b);
template<typename TT> friend Foo<TT> operator + (Foo<TT>& a, TT& element);
};
template<typename T>
Foo<T>::Foo(T arg) {
bar = arg;
}
template<typename T>
Foo<T> operator + (Foo<T>& a, Foo<T>& b) {
return Foo<T>(b.bar);
}
template<typename T>
Foo<T> operator + (Foo<T>& a, T& element) {
return Foo<T>(element);
}
main.cpp:
int main() {
Foo<int> f(5);
Foo<int> g(3);
f + g;//works fine
f + 5;//generates error
system("PAUSE");
return 0;
};
сообщение об ошибке:
ошибка C2679: двоичный '+': оператор не найден, который принимает ручной операнд right- типа 'int' (или нет приемлемого преобразования) [путь к файлу]/main.cpp [название проекта здесь]
Кроме того, построение окна вывода в Visual Studio 2013 показывает:
main.cpp [file-path]\main.cpp(43): ошибка C2679: двоичный '+': оператор не найден, который принимает ручной операнд right- типа 'int' (или нет приемлемого преобразования)
[file path]\foo.h(27): could be 'Foo<int> operator +<int>(Foo<int> &,T &)' with [ T=int ] while trying to match the argument list '(Foo<int>, int)'
Попытка использовать, скажем, функцию template<typename TT> friend Foo<TT> add (Foo<TT>& a, TT& element);
дает аналогичные результаты.
Я также попробовал переслать объявление как класс шаблона, так и проблемную функцию (и добавление <>
перед списком аргументов), но это не помогло.
Я не пропустил что-то очевидное здесь, не так ли?
Ваша проблема сводится к следующему:
struct Foo {};
Foo operator+(Foo&, int&) { return Foo(); }
int main()
{
Foo f1;
Foo f2 = f1 + 42;
}
Ваши параметры являются неконстантными ссылками, и вы передаете аргументы, которые не могут быть связаны с ними (42 в моем примере, 5 в вашем). Вы можете исправить это изменение параметров оператора на const
ссылки. Это имеет смысл, так как бинарный оператор не должен менять свои операнды. Приведенный выше пример можно зафиксировать следующим образом:
Foo operator+(const Foo&, const int&) { return Foo(); }
const
ссылочными параметрами вместо неконстантных? Нет причины, по которойoperator+
должен менять свои аргументы.