考虑一下简单的代码:
struct A; struct B { B(){} B(A const&){ } }; struct A { operator int() const {return 0;}; }; void func(B){} void func(char){} int main() { func(A()); //ambiguous call oO }
首先,我不确定我是否理解正确的一切,所以当你发现我错了时请纠正我.
我的理解是,该void func(B)
已选定,由于参数func
是A
它是类的类型,因此需要转换的类型是"用户定义的转换序列"
现在来自IBM C++ ref:
用户定义的转换序列包括以下内容:
标准转换序列
用户定义的转换
第二个标准转换序列
现在有两个用户定义的转换存在
B::B(const A&)
和A::operator int (const A&);
所以顺序是
- > A()
- > B::B(const A&)
- >Standard conversion (identity conversion)
- > A()
- > A::operator int (const A&)
- >Standard conversion (integral conversion)
因为积分转换比我认为void func(B)
会调用的身份转换更糟糕,但仍然调用是模糊的.
所以,请帮助我,我错了,为什么电话不明确.非常感谢 :)
这里有两个转换序列,A -> B
并且A -> int
都是用户定义的,因为它们通过您定义的函数进行操作.
用户定义的转换序列排序规则见13.3.3.2(N3797):
用户定义的转换序列
U1
是比另一个用户定义的转换序列更好的转换序列,U2
如果它们包含相同的用户定义的转换函数或构造函数,或者它们在聚合初始化中初始化相同的类,并且在任何一种情况下,第二个标准转换序列U1
是优于第二标准转换序列U2
这两个转换序列不包含相同的用户定义转换函数,并且它们不会在聚合初始化中初始化相同的类(因为一个初始化int
).
因此,一个序列排在另一个之上并不是真的,因此这个代码是模糊的.