Ang*_*tis 8 c++ overload-resolution
考虑一下简单的代码:
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
}
Run Code Online (Sandbox Code Playgroud)
首先,我不确定我是否理解正确的一切,所以当你发现我错了时请纠正我.
我的理解是,该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).
因此,一个序列排在另一个之上并不是真的,因此这个代码是模糊的.