为什么两个函数并不含糊

Why two functions are not ambiguous?

本文关键字:函数 不含糊 两个 为什么      更新时间:2023-10-16

我有遗留代码,它有以下构造函数。

CAgs (int ar, bool isReady);
CAgs (int ar, const char* options[][2] = NULL); 

它正在编译,但它不会是含糊的调用吗?如果我调用CAgs (10, 0);,会调用哪个构造函数?

这种行为是否依赖于编译器?

它应该是不明确的。

gcc

叮当

vc++

调用CAgs (10, 0);是不明确的,因为int 0bool指针的候选者。然而,非零int将调用CAgs (int ar, bool isReady);,因为在非零情况下,bool唯一的候选者。

intbool以及0到指针都是积分转换(4.7[conv.integral]),因此两个转换的顺序相同,这使得它们不明确。然而,这仅适用于int是像NULL0那样的所谓空指针常数的情况,否则int到指针的转换不是候选的,并且选择了intbool的转换。

这是不明确的。要解决此问题,需要显式强制转换,如:

CAgs(4, (bool)0);

CAgs(4, (char *)0);

积分转换

整数类型或无范围枚举类型的prvalue可以是转换为任何其他整数类型。如果转换列在整体促销,这是一种促销,而不是转换。

  • 如果目标类型是无符号的,则得到的值是最小的无符号值,等于源值模2n其中n是用于表示目的地类型的比特数
  • 也就是说,根据目标类型是宽还是窄,有符号整数分别是符号扩展的[脚注1]或截断的,无符号整数和零扩展的或截断的
  • 如果目标类型是带符号的,则如果源整数可以在目标类型中表示,则该值不会更改。否则,结果就是实现定义的
  • 如果源类型为bool,则值false将转换为零,值true将转换为destination类型(注意,如果destination类型为int,则是整数提升,而不是整数转换)
  • 如果目标类型为bool,则这是一个布尔转换(请参阅以下)

指针转换

  • 空指针常量(请参见null)可以转换为任何指针类型,结果是该类型的空指针值。这种转换(称为空指针转换)可以作为单个转换转换为cv限定类型,也就是说,它不被视为数字转换和限定转换的组合
  • 指向任何(可选cv限定的)对象类型T的prvalue指针可以转换为指向(完全cv限定)无效的结果指针表示内存中与原始指针值。如果原始指针为null指针值,结果是目的地类型
  • 指向(可选cv限定的)派生类类型的prvalue指针可以转换为指向其可访问、明确(完全cv限定)基类的prvalue指示器。转换的结果是指向指向对象中基类子对象的指针。空指针值转换为空指针值目的地类型的

布尔转换

整型、浮点、无范围枚举、指针的Prvalues,并且指向成员类型的指针可以转换为布尔类型的prvalue。

值零(用于整型、浮点型和无范围枚举)以及指向成员的空指针和空指针值变为false。所有其他值都变为真。

std::nullptr_t类型的Prvalue,包括nullptr,可以在直接初始化的上下文中转换为bool类型的Prvalue(从C++14开始)。结果值为false。

来源:cppreference 的隐式转换

由于它们都是转换,所以它们有相同的顺序,所以这应该是不明确的。但只有在0的情况下,因为0可以转换为NULL。

Nb。我将您的问题解释为"它为什么要编译?如果我这样称呼它,这不是很模糊吗?"

该调用是不明确的,因为调用每个构造函数都需要使用CAgs (10, 0); 进行隐式转换

引用一些来源:

§4.10.1对于const char* options[][2]

空指针常量是值为零的整数文字(2.14.2)或std::nullptr_t类型的prvalue。空指针常量可以是转换为指针类型;结果是的空指针值该类型,并且可以与对象的其他值区分开来指针或函数指针类型。这样的转换称为null指针转换。

4.12.1对于bool

算术、无范围枚举、指针或指向的指针的prvalue成员类型可以转换为布尔类型的prvalue。零值,null指针值,或null成员指针值转换为虚假;任何其他值都转换为true。

代码肯定会编译,因为参数是两种不同的有效类型,如果您传递的东西不需要模糊的隐式转换,它就会正常工作。但这并不意味着它对CAgs (10, 0); 来说并不含糊

作为一个无关的小旁注,指针的默认值使以下内容正常工作:CAgs (10);。对于任何其他非零类型也是如此(将选择bool构造函数)。