为什么 std::initializer_list 转换不是首选?

Why is std::initializer_list conversion not preferred?

考虑这个片段:

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

Live on Coliru

如果你 运行 它,你可以看到 f(int) 重载是首选,即使 std::vector 有一个 std::initializer_list constructor (见#8)。

问题:为什么首选 {42}int 的转换(而不是转换到 std::vector,因为 {42}std::initializer_list)?

在重载决议中,当考虑implicit conversion sequence in list-initialization

(强调我的)

Otherwise, if the parameter type is not a class and the initializer list has one element, the implicit conversion sequence is the one required to convert the element to the parameter type

给定f({42});,对于f(int),隐式转换序列是将元素(即42)转换为int的序列,这是一个精确匹配;对于 f(std::vector<int>),需要用户定义的转换(将 std::initializer_list<int> 转换为 std::vector<int>),那么这是一个较差的匹配。

PS:如果花括号初始化器包含多个元素,例如{42, 42},将选择f(std::vector<int>)