当前位置: 首页 > 知识库问答 >
问题:

如果使用“促销”,为什么隐式转换序列不是最好的ICS?

沈运恒
2023-03-14

编译这段代码:

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);
}

如果我为< code>foo定义了< code > int -转换运算符而不是char,许多编译器会发现调用< code>func(a)有歧义,只有一个编译器发现它没有歧义。

https://godbolt.org/g/zhRJZB

阅读标准,我不期望这样,因为:

如果我编译 #2,则结构 a 是从 foo 转换而来的 -

(1) foo ->  char : char -> char
(2) foo ->  char : char -> int 
(3) foo ->  float : float -> int
(3) foo ->  float : float -> char

转换char-

在案例 #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

所以在这个候选集中,应该只有隐式转换序列比其他更好。

有人能解释一下为什么代码应该是模棱两可的吗?


共有1个答案

冉伯寅
2023-03-14
匿名用户

因为重载解析不会直接比较四个转换。

在第二种情况下,重载决策首先假设选择了< code>int func(int),然后找到

foo -> char  : char -> int is better than
foo -> float : float -> int

因此转换foo-

foo -> char  : char -> char is better than
foo -> float : float -> char

因此转换foo-

foo -> char  : char -> char is better than
foo -> char  : char -> int

重载解析最终选择int func(char)以及转换foo-

#1种情况类似,但重载解析无法确定在假定选择了int func(char)时选择哪种转换。在这种情况下,重载解析引入了一个不明确的转换序列,用于比较与两个func对应的隐式转换序列(以确定要选择哪个func)。模棱两可的转换序列与任何用户定义的转换序列无法区分,因此结果是模棱两角的。

引自[over.best.ics]/10:

如果存在多个不同的转换序列,每个转换序列都将参数转换为参数类型,则与参数关联的隐式转换序列被定义为指定为不明确转换序列的唯一转换序列。为了对 [over.ics.rank] 中所述的隐式转换序列进行排名,不明确的转换序列被视为用户定义的转换序列,该序列与任何其他用户定义的转换序列都无法区分。

 类似资料:
  • 以下代码在C++11中编译成功: 它包括用于现代C++的JSON。一个工作示例在这个Wandbox中。 JSON变量被隐式转换为字符串。但是,如果我取消最后一行的注释,这是一个显式转换,它将无法编译。这里的编译结果。 除了这个json库的特殊细微差别之外,如何编写一个类,使隐式转换工作,而显式转换不工作? 是否有某种构造函数限定符允许这种行为?

  • 问题内容: 您可以将int隐式转换为double: 您可以将int显式转换为double: 您可以将double显式转换为int: 为什么不能将一个double隐式转换为int? : 问题答案: 的范围比宽。这就是为什么您需要显式强制转换。由于相同的原因,您不能隐式地从转换为:

  • 我有一个奇怪的行为,我想了解它。但我在网上没有找到好的答案:( 情况是这样的,我抽象了名称和逻辑来关注这个问题。有三种类型,A型,B型和c型 然后,当我这样做时,代码编译并正常工作: 但当我用内联if编写相同的逻辑时,我得到了一个错误: 错误: 你对这种行为有什么想法吗? 提前感谢您的宝贵时间。 最好的问候,并保持它的错误自由!

  • 问题内容: Java 1.5 的Java序列化规范说: 对于可序列化的对象,运行第一个不可序列化超类型的no- arg构造函数。对于可序列化的类,将字段初始化为适合其类型的默认值。然后,通过调用特定于类的readObject方法来恢复每个类的字段,如果未定义这些字段,则通过调用defaultReadObject方法来恢复它们。请注意,在反序列化期间,不会为可序列化的类执行字段初始化程序和构造函数。

  • 问题内容: 我可以隐式地将int转换为long,并将long转换为Long。为什么无法将int隐式转换为Long?为什么Java不能在示例的最后一行进行隐式转换? 问题答案: 和是对象。装箱/拆箱仅适用于原语。做的就像,那不是不!另外,请记住,之间没有继承,所以甚至无效