编译这段代码:

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/

10-12 14:24
查看更多