为什么不推荐使用std::initializer_list转换?

11

考虑以下片段:

#include <iostream>
#include <vector>

void f(std::vector<int>){std::cout << __PRETTY_FUNCTION__ << '\n';}
void f(int x){std::cout << __PRETTY_FUNCTION__ << '\n';}

int main() 
{
    f({42});
}

在 Coliru 上实时运行,你会发现即使 std::vector 有一个std::initializer_list 构造函数(参见#8),f(int) 重载也更被优先使用。

问题:为什么将 {42} 转换为 int 更优先(而不是转换为 std::vector,因为 {42}std::initializer_list)?


这个标签是[c++11],但链接的Coliru是使用-std=c++17编译的。这种不一致感觉不太对,尽管它不会影响问题。 - user2486888
5
{42}不是一个std::initializer_list,它是用花括号括起来的一个int。它不是一个表达式,也没有类型。 - M.M
@NickyC modified - vsoftco
1个回答

16
在重载决议中,考虑列表初始化中的隐式转换序列时,
(强调是我的)
如果参数类型不是类,并且初始化列表只有一个元素,则隐式转换序列是将该元素转换为参数类型所需的序列。
对于f(int),给定f({42});,隐式转换序列是将元素(即42)转换为int,这是一个精确匹配;对于f(std::vector<int>),需要用户定义的转换(将std::initializer_list<int>转换为std::vector<int>),然后它是一个更差的匹配。
PS:如果大括号初始化程序包含多个元素,例如{42, 42},则选择f(std::vector<int>)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接