繁体   English   中英

为什么不缩小会影响重载分辨率?

[英]Why doesn't narrowing affect overload resolution?

考虑以下:

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

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

这无法编译,但有关A::A的模糊重载的错误。 两位候选人都被认为是可行的,因为要求很简单

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

虽然存在从doubleint的隐式转换序列,但A(int )重载实际上不可行(在规范的,非C ++标准意义上) - 这将涉及缩小转换并因此形成错误。

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

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

在C ++中,有很复杂的方法可以在编译时生成值。

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

在确定过载分辨率时忽略缩小转换规则(这使得过载分辨率完全与类型有关),然后在所选过载导致转换变窄时出错,使过载分辨率变得更加复杂,并增加了检测和防止的方法缩小转换率。

只有一个候选者可行的两个例子是在实例化期间“迟到”失败的模板函数,以及复制列表初始化(考虑explicit构造函数,但如果选择它们,则会出现错误)。 类似地,具有该影响的重载分辨率将使重载分辨率比现在更复杂。

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

缩小转换纯粹是基于类型的转换是不可行的。 这些更改可能会破坏编译器可能证明有效的大量“遗留”代码。 当大多数错误是实际错误而不是新的编译器版本是一个混蛋时,扫描代码库所需的工作更有价值。

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

这将在基于类型的缩小转换下失败,因为0xff的类型为int ,并且此类代码非常常见。

如果这样的代码需要毫无意义地将int文字修改为unsigned char literals,那么我们设置一个标志来告诉编译器关闭愚蠢的错误,那么扫描就会结束。

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

  • 首先,不应允许缩小转换。 (不幸的是,这是C兼容性所必需的。在{}初始化禁止缩小内置类型的情况下,这已得到一定程度的纠正。)

鉴于这些,过载规则无需提及这种特殊情况是有道理的。 这可能是偶然的便利,但并不是那么有价值。 IMO通常会更好地减少重载决策所涉及的因素,并拒绝更多不明确的事情,迫使程序员明确地解决这些问题。


另外,当double不是常量表达式或double太大时,double to float是缩小转换。

#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};
            ^

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM