【问题标题】:Why two functions are not ambiguous?为什么两个函数没有歧义?
【发布时间】:2014-09-18 09:32:35
【问题描述】:

我有具有以下构造函数的遗留代码。

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

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

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

【问题讨论】:

  • 隐式转换是标准化的。
  • 在这种情况下我会使用“显式”
  • @MarcoA.:你的意思是第二个,因为它CAgs 大概不是大数字类型?
  • It is ambiguous,你用的是什么编译器?我没听错吗?
  • @pranitkothari 它可以编译,但这并不意味着如果你这样调用构造函数就没有歧义。如果你将你想要接收的类型传递给它,它就不会模棱两可

标签: c++ oop overloading ambiguity


【解决方案1】:

应该是模棱两可的。

gcc

clang

vc++

【讨论】:

    【解决方案2】:

    调用CAgs (10, 0); 是模棱两可的,因为int 0bool 的候选对象一个指针。非零 int 会调用 CAgs (int ar, bool isReady);,但是因为 bool 是非零情况下的唯一候选者。

    【讨论】:

    • 在它是一个指针之前?值会经历某种类型的数据类型转换?
    • 这对我来说是违反直觉的。 0 比我理解的布尔值更接近于表示内存地址。你有参考吗?
    • 我认为您将不得不用一些参考资料来支持这一点:-)
    【解决方案3】:

    intbool 以及 0 到指针都是一个积分转换 (4.7 [conv.integral]),因此这两个转换具有相同的顺序,这使得它们模棱两可.但是,这仅适用于 int 是所谓的 空指针常量,例如 NULL0,否则 int 到指针的转换不可行,int 到 @ 987654329@一个被选中了。

    【讨论】:

      【解决方案4】:

      这是模棱两可的。要解决此问题,需要显式转换,例如:

      CAgs(4, (bool)0);
      

      CAgs(4, (char *)0);
      

      【讨论】:

        【解决方案5】:

        积分转换

        整数类型或无作用域枚举类型的纯右值可以是 转换为任何其他整数类型。如果转换列在下面 积分促销,是促销,不是转化。

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

        ...

        指针转换

        • 空指针常量(参见 NULL)可以转换为任何指针类型,结果是该类型的空指针值。此类转换(称为空指针转换)允许作为单一转换转换为 cv 限定类型,也就是说,它不被视为数字和限定转换的组合。
        • 指向任何(可选 cv 限定)对象类型 T 的 prvalue 指针可以转换为指向(同样 cv 限定)的 prvalue 指针 空白。结果指针表示内存中的相同字节 原始指针值。如果原始指针为空 指针值,结果是一个空指针值 目的地类型。
        • 指向(可选 cv 限定)派生类类型的纯右值指针可以转换为指向其可访问的、明确的(相同 cv 限定的)基类的纯右值指针。转换的结果是指向指向对象内的基类子对象的指针。空指针值转换为空指针值 目标类型。

        ...

        布尔转换

        整型、浮点型、无范围枚举、指针的纯右值, 和指向成员类型的指针可以转换为 bool 类型的纯右值。

        零值(用于整数、浮点和无作用域 枚举)和空指针和指向成员的空指针 值变为假。所有其他值都变为 true。

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

        来源:Implicit conversions@cppreference

        由于它们都是转换,它们具有相同的顺序,所以这应该是模棱两可的。但仅限于0的情况,因为0可以转换为NULL。

        【讨论】:

          【解决方案6】:

          铌。我将您的问题解释为“为什么它会编译?如果我是这样称呼它不是很模糊吗?”

          调用is ambiguous 因为调用每个构造函数都需要使用CAgs (10, 0); 进行隐式转换

          引用一些资料:

          const char* options[][2] 类型的第 4.10.1 节

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

          bool 类型为 4.12.1

          算术、无范围枚举、指针或指向的指针的纯右值 成员类型可以转换为布尔类型的纯右值。一个零值, 空指针值,或空成员指针值转换为 错误的;任何其他值都将转换为 true。

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

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

          【讨论】:

            猜你喜欢
            • 2015-10-06
            • 2013-03-21
            • 2015-10-28
            • 1970-01-01
            • 2011-02-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多