[英]Overload resolution of int vs std::vector<int> with an initializer list of a single int
为什么 c++ 选择原始类型重载匹配而不是“更好”匹配的初始值设定项列表?
#include <vector>
void foo([[maybe_unused]] int i) {}
void foo([[maybe_unused]] const std::vector<int>& v) {}
int main() {
foo(0);
foo({1,2,3});
foo({0}); // calls foo(int) and issues a warning,
// rather than what seems like the "better"
// match foo(vector).. why?
}
<source>:10:9: warning: braces around scalar initializer [-Wbraced-scalar-init]
foo({0}); // calls foo(int) and issues a warning,
^~~
也许“令人惊讶”的结果,因为编译器选择了它然后发出诊断的选项?
使用 Clang 14
{0}
没有类型,因此我们需要尝试将其转换为重载集的参数类型。 考虑时
void foo([[maybe_unused]] const std::vector<int>& v) {}
我们需要查阅[over.ics.list]/7.2中的说明
否则,隐式转换序列是用户定义的转换序列,其第二个标准转换序列是恒等转换。
所以我们为这个转换序列有一个用户定义的转换。
看着
void foo([[maybe_unused]] int i) {}
我们发现[over.ics.list]/10.1中涵盖的转换指出
如果初始化器列表有一个元素本身不是初始化器列表,则隐式转换序列是将元素转换为参数类型所需的序列;
这种情况下的元素是0
,它是一个 integer 文字,它是一个完全匹配的标准转换
所以现在我们有一个用户定义的转换与一个标准的转换,这被[over.ics.rank]/2.1
标准转换序列是比用户定义的转换序列或省略号转换序列更好的转换序列,并且
现在我们知道标准转换是更好的转换,这就是为什么选择int
重载而不是std::vector<int>
重载的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.