“运算符”的 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
C++ ambiguous overload for ‘operator ’
提问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 + 4
could 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)
explicit
so 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
int
toFraccao
: Make the constructorexplicit
. Forbid implicit conversion from
Fraccao
toint
: Make the conversion operatorexplicit
.Convert manually on the callers side, given
Fraccao f; int i;
eitherint(f)+i
orf+Fraccao(i)
.Provide additional overloads to resolve the ambiguity:
- 禁止从
int
to隐式转换Fraccao
:构造构造函数explicit
。 Forbid 隐式转换 from
Fraccao
toint
:使转换操作符explicit
。手动转换在呼叫者一侧,给定的
Fraccao f; int i;
任一int(f)+i
或f+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 4
to an object of type Fraccao
and use operator+(const Fraccao&, const Fraccao&)
or it can convert a
to type int
with the member conversion operator, and add 4
to 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)标记,代码就可以了。