Bar*_*rry 25 c++ language-lawyer overload-resolution c++11
考虑以下:
struct A {
A(float ) { }
A(int ) { }
};
int main() {
A{1.1}; // error: ambiguous
}
Run Code Online (Sandbox Code Playgroud)
这无法编译时出现关于模糊重载的错误A::A
.两位候选人都被认为是可行的,因为要求很简单:
第二,为了
F
成为一个可行的函数,每个参数都应该存在一个隐式转换序列(13.3.3.1),它将该参数转换为相应的参数F
.
虽然存在从隐式转换序列double
到int
,该A(int )
过载不是实际可行的(在规范,非C++ -标准的意义上) -这将涉及一个收缩转换,因此是形成不良.
为什么在确定可行的候选人的过程中不考虑缩小转换?尽管只有一个候选人可行,但是有没有其他情况下过载被认为是模棱两可的?
Yak*_*ont 15
问题在于可以不基于类型检测缩小转换的事实.
在C++中,有很复杂的方法可以在编译时生成值.
阻止缩小转换是一件好事.使C++的重载分辨率比现在更复杂是一件坏事.
在确定过载分辨率时忽略缩小转换规则(这使得过载分辨率完全与类型有关),然后在所选过载导致转换变窄时出错,使过载分辨率变得更加复杂,并增加了检测和防止的方法缩小转换率.
只有一个候选者可行的两个例子是在实例化期间"迟到"失败的模板函数,以及复制列表初始化(explicit
考虑构造函数,但如果选择它们,则会出现错误).类似地,具有该影响的重载分辨率将使重载分辨率比现在更复杂.
现在,有人可能会问,为什么不将纯粹的转换缩小到类型系统?
缩小转换纯粹是基于类型的转换是不可行的.这些更改可能会破坏编译器可能证明有效的大量"遗留"代码.当大多数错误是实际错误而不是新的编译器版本是一个混蛋时,扫描代码库所需的工作更有价值.
unsigned char buff[]={0xff, 0x00, 0x1f};
Run Code Online (Sandbox Code Playgroud)
这会在类型的缩小转换下失败,就像0xff
类型一样int
,并且这种代码非常常见.
如果这样的代码需要对int
文字进行毫无意义的文字修改,那么unsigned char
我们设置一个标志来告诉编译器关闭愚蠢的错误,可能会导致扫描结束.
缩小是编译器只知道内置类型的东西.用户定义的隐式转换不能标记为缩小.
首先,不应允许缩小转换.(不幸的是,它是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';
}
Run Code Online (Sandbox Code Playgroud)
这通常会产生错误:
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};
^
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
736 次 |
最近记录: |