c++ - 为什么缩小不影响重载分辨率?

标签 c++ c++11 language-lawyer overload-resolution

考虑以下几点:

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

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

编译失败,出现关于 A::A 不明确重载的错误。两个候选者都被认为是可行的,因为 requirement is simply :

Second, for F to be a viable function, there shall exist for each argument an implicit conversion sequence (13.3.3.1) that converts that argument to the corresponding parameter of F.

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

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

最佳答案

一个问题在于,可以不基于类型来检测缩小转换。

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

阻止缩小转化是一件好事。让 C++ 的重载解析比现在更加复杂是一件坏事。

在确定重载决议时忽略缩小转换规则(这使得重载决议纯粹与类型有关),然后在选定的重载导致缩小转换时出错,防止重载决议变得更加复杂,并以某种方式添加检测并防止缩小转化。

只有一个候选者可行的两个示例是模板函数在实例化期间“延迟”失败,以及复制列表初始化(其中考虑了 explicit 构造函数,但如果选择了它们,您得到一个错误)。同样,具有这种影响的重载解决方案会使重载解决方案比现在更加复杂。

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

使缩小转换纯粹基于类型是不可行的。此类更改可能会破坏编译器可以证明有效的大量“遗留”代码。当大多数错误是实际错误而不是新的编译器版本是个 SCSS 时,清理代码库所需的工作就更值得了。

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

这在基于类型的窄化转换下会失败,因为 0xff 的类型是 int,这样的代码很常见。

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

关于c++ - 为什么缩小不影响重载分辨率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31730222/

相关文章:

c++ - 解锁保护(或 boost::reverse_lock)是反模式吗?为什么?

C++ 虚拟方法,不需要 "this"指针 - 优化

c++ - 为什么我可以将采用按值参数的函数绑定(bind)到采用左值引用的 std::function?

c++ - 从真值到 std::true_type 的隐式转换

c++ - 转换不同参数类型的二元运算函数

c - 在C89中有效的程序,但在C99中无效

c++ 为什么 decltype(*pointer) 产生一个引用?

c++ - 使用 'assert' 验证参数数量

c++ - 合并和快速排序 - 堆栈重载

c++ - 当短路禁用其评估时,正在读取常量表达式中允许的尾数指针