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

为什么缩小不影响重载解析?

赫连子石
2023-03-14

请考虑以下情况:

struct A {
    A(float ) { }
    A(int ) { }
};

int main() {
    A{1.1}; // error: ambiguous
}

这将无法编译,并出现关于< code>A::A的不明确重载的错误。两个候选人都被认为是可行的,因为要求很简单:

其次,为了使 F 成为一个可行的函数,每个参数都应该存在一个隐式转换序列 (13.3.3.1),该序列将该参数转换为 F 的相应参数。

虽然有一个从<code>double</code>到<code>int</code>的隐式转换序列,但<code>A(int)</code>重载实际上是不可行的(在规范的非C标准意义上),这将涉及一个窄化转换,因此是病态的。

为什么在确定可行的候选人的过程中没有考虑缩小转换范围?是否有任何其他情况,尽管只有一个候选人可行,但过载被认为是模棱两可的?

共有2个答案

雷锋
2023-03-14

>

  • 缩小是编译器只知道内置类型的事情。用户定义的隐式转换不能标记为缩小或不缩小。

    缩小转化范围首先不应被允许隐式进行。(不幸的是,它是C兼容性所必需的。这已通过 {} 初始化进行了一定程度的纠正,该初始化禁止对内置类型进行缩小。

    考虑到这些,重载规则不必提及这种特殊情况是有道理的。这可能只是偶尔的方便,但也不是那么有价值。在我看来,一般来说,在重载解析中涉及的因素越少越好,而拒绝更多模糊的内容,迫使程序员显式解析这些内容。

    此外,双精度到浮点数是当双精度不是常量表达式或双精度太大时的缩小转换。

    #include <iostream>
    #include <iomanip>
    
    int main() {
        double d{1.1};
        float f{d};
        std::cout << std::setprecision(100) << d << " " << f << '\n';
    }
    

    这通常会产生错误:

    main.cpp:7:13: error: non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list [-Wc++++11-narrowing]
        float f{d};
                ^
    

  • 孙修贤
    2023-03-14

    问题在于可以检测到不基于类型的缩小转换。

    在C中编译时生成值的方法非常复杂。

    阻止缩小转换范围是一件好事。使C的重载分辨率比现在更复杂是一件坏事。

    在确定重载分辨率时忽略窄化转换规则(这使得重载分辨率完全与类型有关),然后在选定的重载导致窄化转换时出错,可以避免重载分辨率变得更复杂,并以某种方式检测和防止窄化转换。

    只有一个候选项可行的两个示例是在实例化期间“延迟”失败的模板函数,以及副本列表初始化(其中考虑显式构造函数,但如果选择了它们,则会收到错误)。同样,具有这种影响过载分辨率将使过载分辨率比现在更加复杂。

    现在,有人可能会问,为什么不将缩小转换纯粹折叠到类型系统中呢?

    使窄化转换完全基于类型是不可行的。这样的更改可能会破坏编译器可以证明有效的大量“遗留”代码。当大多数错误都是实际错误,而不是新的编译器版本是一个错误时,清理代码库所需的努力就更有价值了。

    unsigned char buff[]={0xff, 0x00, 0x1f};
    

    这在基于类型的缩小转换下会失败,因为0xffint类型的,并且这样的代码非常常见。

    如果这样的代码需要对int文本进行毫无意义的修改,那么扫描很可能会以我们设置一个标志来告诉编译器对愚蠢的错误闭嘴而告终。

     类似资料:
    • 下面是vb中的一个特殊情况。我搞乱了SuppressKeyPress属性,发现了一些奇怪的东西。 形势 假设我有一个名为的输入框,我希望名称不带任何数字,当插入数字时,会弹出一个MessageBox并报告错误。 在这种情况下,由于某种奇怪的原因,如果我键入一个数字,它将被写入文本框中,尽管我抑制了按键。 我发现,如果我删除MsgBox行,数字将不会出现在输入框中。 问题 这是怎么回事?为什么Msg

    • 如果我的理解是正确的,那么为什么不将的==和!=运算符重载为: 那我们就可以省下两个铸件了?

    • 根据定义: noNamespaceSchema位置属性引用没有目标命名空间的XML Schema文档。 这个属性将如何改变解析的结果? 例如,以这个XML为例: 参考此模式: 我从架构中删除了以下命名空间声明: 即使在引用XML中不使用noNamespaceSchemaLocation属性,也不会引发错误。为什么我们一开始就需要这个属性?

    • 我是css的新手,我正在尝试css注入,我在浏览器上更改主页的属性。 我有一个元素b,它有一个祖先a(不是直接的,中间有几个步骤)。 我读过很多次,通过在类之间使用空格,例如,您可以选择属于a类对象的后代的所有b类对象。 因此,注入会按预期将我的对象的颜色更改为白色。但是只使用不是,这一点我不理解,因为它应该影响b类的所有对象,不管它们的祖先是什么?

    • Java,当我重写一个方法时,编译器会将任何缩小可见性的尝试标记为错误。例如:我不能将公共方法重写为受保护的,而我可以将受保护的方法重写为公共的。 我有兴趣了解这条规则背后的设计决策/思维。