为什么 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});
}
如果你 运行 它,你可以看到 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>)
。
考虑这个片段:
#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});
}
如果你 运行 它,你可以看到 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>)
。