【问题标题】:Error C2679 when using '+' operator in a template to add template class and parameter class在模板中使用“+”运算符添加模板类和参数类时出现错误 C2679
【发布时间】:2014-01-05 10:36:31
【问题描述】:

我正在尝试创建一个模板类来表示一组元素,这些元素以两种方式重载“+”运算符: 像这样: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:二进制“+”:未找到采用“int”类型右手操作数的运算符(或没有可接受的转换)[文件路径]/main.cpp [此处的项目名称]

此外,Visual Studio 2013 中的构建输出窗口显示:

main.cpp [file-path]\main.cpp(43): error C2679: binary '+' : no operator found which采用'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&lt;typename TT&gt; friend Foo&lt;TT&gt; add (Foo&lt;TT&gt;&amp; a, TT&amp; element); 会产生类似的结果。

我还尝试前向声明模板类和有问题的函数(并在参数列表前添加&lt;&gt;),但这没有帮助。

我没有遗漏一些明显的东西,是吗?

【问题讨论】:

  • 您可以尝试使用const 引用参数而不是非常量吗? operator+ 没有理由改变它的论点。
  • 哦。谢谢。它实际上似乎已经解决了这个问题。我只需要稍微测试一下实际代码,看看我是否没有草率下结论。
  • 好的,我用一个非常简化的例子添加了答案。

标签: c++ visual-studio templates operator-overloading


【解决方案1】:

您的问题可以归结为:

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(); }

【讨论】:

  • 是的,这就是问题所在。非常感谢!
  • @Dragomok 很高兴它有帮助。将来,您可能会尝试将问题归结为最小的问题,例如我的答案中的示例。它将帮助您更好地理解问题,您甚至可以自己解决问题,或者如果没有,它会让其他人更容易解决。
猜你喜欢
  • 1970-01-01
  • 2016-05-28
  • 2020-10-17
  • 1970-01-01
  • 2021-02-17
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多