编译这段代码:
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
转换运算符而不是 char,许多编译器会发现调用 func(a)
不明确,只有 1 个编译器发现它没有歧义。
阅读标准,我并不期待,因为:
如果我编译 #2
结构 a
从 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
是一个提升,所以这个转换 (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
因此,如果选择 int func(int)
,则会考虑转换 foo -> char : char -> int
。类似地,如果选择了 int func(char)
,那么它会找到
foo -> char : char -> char is better than
foo -> float : float -> char
因此,如果选择 int func(char)
,则会考虑转换 foo -> char : char -> 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
选择)。模棱两可的转换序列与任何用户定义的转换序列都无法区分,因此结果是模棱两可的。
If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as described in [over.ics.rank], the ambiguous conversion sequence is treated as a user-defined conversion sequence that is indistinguishable from any other user-defined conversion sequence.
关于c++ - 如果使用 "Promotion",为什么隐式转换序列不是最好的 ICS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49326292/