编译这段代码:
int func( int ) {
return 1;
}
int func( char ) {
return 2;
}
struct foo {
operator int() { // Call to 'func(a)' is ambigous #1
// operator char() { // Call to 'func(a)' is not ambigous #2
return 1;
}
operator float() {
return 0.f;
}
};
int test_it (void) {
foo a;
return (func(a)==2);
}
如果我为
foo
定义int
-conversion运算符而不是char,很多编译器会发现调用func(a)
模棱两可,只有1个编译器发现它不是模棱两可。https://godbolt.org/g/zhRJZB
阅读该标准,我并不期望这样,因为:
如果我编译
#2
,则从a
转换struct foo -> char
,然后再将char -> char
转换为以下候选集的最佳隐式转换序列(ICS):(1) foo -> char : char -> char
(2) foo -> char : char -> int
(3) foo -> float : float -> int
(3) foo -> float : float -> char
转换
char -> int
是促销 Activity ,因此此转换(2)的排名为“促销”,比“完全匹配”(1)差,float -> int
是(3)“转换”如果是
#1
: foo -> int : int -> int
应该是最好的ICS,因为:
(1) foo -> int : int -> int better than
(3) foo -> int : int -> char
(3) foo -> float : float -> int
(3) foo -> float : float -> char
因此,在此候选集中,应仅使用隐性转换序列,该序列要比其他序列好。
有人可以解释一下为什么代码不明确吗?
最佳答案
因为重载解析不会直接比较这四个转换。
在#2情况下,重载解决方案首先假定已选择int func(int)
,然后找到
foo -> char : char -> int is better than
foo -> float : float -> int
因此,如果选择了
foo -> char : char -> int
,则要考虑转换int func(int)
。同样,如果选择了int func(char)
,则会找到foo -> char : char -> char is better than
foo -> float : float -> char
因此,如果选择了
foo -> char : char -> char
,则要考虑转换int func(char)
。最后,因为foo -> char : char -> char is better than
foo -> char : char -> int
最终,重载分辨率选择
int func(char)
以及转换foo -> char : char -> char
。#1情况类似,不同之处在于,如果假定
int func(char)
被选择,则重载解析无法确定选择哪种转换来选择。在这种情况下,重载解析会引入一个不明确的转换序列,以比较对应于两个func
的隐式转换序列(以确定要选择的func
)。模糊转换序列与任何用户定义的转换序列都没有区别,因此结果是模糊的。引用自[over.best.ics]/10:
关于c++ - 如果隐式转换序列使用 “Promotion”,为什么不是最佳ICS?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49326292/