“运算符”的 C++ 不明确重载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19819130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:10:09  来源:igfitidea点击:

C++ ambiguous overload for ‘operator ’

c++operatorsoperator-overloading

提问by Godinho

I'v read several posts here about this kind of errors, but I wasn't able to solve this one... Has soon I define the operator int and the function f, fails to compile. I tested several things by I wasn't able to solve the issue.... Thanks

我在这里阅读了几篇关于此类错误的帖子,但我无法解决这个问题...很快我定义了运算符 int 和函数 f,无法编译。我测试了几件事情,但我无法解决问题......谢谢

ex1.cpp: In function ‘int main(int, char**)':
ex1.cpp:35:13: error: ambiguous overload for ‘operator+' in ‘a + 4'
ex1.cpp:35:13: note: candidates are:
ex1.cpp:35:13: note: operator+(int, int) <built-in>
In file included from ex1.cpp:3:0:
Fraccao.h:41:9: note: Fraccao operator+(const Fraccao&, const Fraccao&)
ex1.cpp:38:13: error: ambiguous overload for ‘operator+' in ‘4 + a'
ex1.cpp:38:13: note: candidates are:
ex1.cpp:38:13: note: operator+(int, int) <built-in>
In file included from ex1.cpp:3:0:
Fraccao.h:41:9: note: Fraccao operator+(const Fraccao&, const Fraccao&)

The class:

班上:

class Fraccao {
    int numerador;
    int denominador;

public:
    Fraccao(int num = 0, int deno = 1) : numerador(num), denominador(deno) {}

    Fraccao & operator+=(const Fraccao &fra);

    Fraccao & operator*=(const Fraccao &fra);

    operator int() const;

    const Fraccao & operator++();
    const Fraccao operator++(int);

    string getAsString() const;
};

Fraccao operator +(const Fraccao &a, const Fraccao &b);
ostream & operator<<(ostream & saida, const Fraccao & fra);

And on my main:

而在我的主要:

void func(int n) {
    cout << n; // 
}

int main(int argc, char** argv) {
    //...
    d = a + b;
    const Fraccao h(7, 3);
    func(h);

    return 0;
}

回答by Mike Seymour

You don't seem to have posted the code that actually causes the error. I guess it looks something like

您似乎没有发布实际导致错误的代码。我想它看起来像

Fraccao a;
Fraccao b = a + 4;
Fraccao c = 4 + a;

The problem is that your class allows implicit conversions both to and from int; so a + 4could be either

问题是你的类允许隐式转换 to 和 from int; 所以a + 4可能是

int(a) + 4

or

或者

a + Fraccao(4)

with no reason to choose one over the other. To resolve the ambiguity, you could either:

没有理由选择其中之一。要解决歧义,您可以:

  • make the conversion explicit, as above; or
  • declare either the constructor or the conversion operator (or even both) explicitso that only one (or even neither) conversion can be done implicitly.
  • 使转换显式,如上;或者
  • 声明构造函数或转换运算符(或什至两者),explicit以便只能隐式完成一个(或什至两个都不)转换。

回答by Daniel Frey

You have several options to fix your problem:

您有多种选择来解决您的问题:

  • Forbid implicit conversion from intto Fraccao: Make the constructor explicit.
  • Forbid implicit conversion from Fraccaoto int: Make the conversion operator explicit.

  • Convert manually on the callers side, given Fraccao f; int i;either int(f)+ior f+Fraccao(i).

  • Provide additional overloads to resolve the ambiguity:

  • 禁止从intto隐式转换Fraccao:构造构造函数explicit
  • Forbid 隐式转换 from Fraccaoto int:使转换操作符explicit

  • 手动转换在呼叫者一侧,给定的Fraccao f; int i;任一int(f)+if+Fraccao(i)

  • 提供额外的重载来解决歧义:

Fraccao operator +(const Fraccao &a, const Fraccao &b);
Fraccao operator +(const int a, const Fraccao &b);
Fraccao operator +(const Fraccao &a, const int b);

The latter probably means you also want:

后者可能意味着您还想要:

Fraccao & operator+=(const Fraccao &fra);
Fraccao & operator+=(const int i);

And finally, if you want the latter, you can use libraries like Boost.Operatorsor my df.operatorsto support you and avoid writing the same forwarders over and over again.

最后,如果你想要后者,你可以使用像Boost.Operators或我的df.operators这样的库来支持你,避免一遍又一遍地编写相同的转发器。

回答by Pete Becker

The compiler sees two ways to interpret a + 4. It can convert the 4to an object of type Fraccaoand use operator+(const Fraccao&, const Fraccao&)or it can convert ato type intwith the member conversion operator, and add 4to the result. The rules for overloading make this ambiguous, and that's what the compiler is complaining about. In general, as @gx_ said in a comment, this problem comes up because there are conversions in both directions. If you mark the operator int()with explicit(C++11) the code will be okay.

编译器看到两种解释a + 4. 它可以将 转换4为类型的对象Fraccao并使用operator+(const Fraccao&, const Fraccao&),也可以使用成员转换运算符转换a为类型int,并添加4到结果中。重载规则使这变得模棱两可,这就是编译器所抱怨的。一般来说,正如@gx_ 在评论中所说,出现这个问题是因为双向都有转换。如果你operator int()explicit(C++11)标记,代码就可以了。