c++ - 在单元素列表中,C++ 强制 std::vector 重载而非int重载

  显示原文与译文双语对照的内容
111 3

考虑下面的代码:

#include <iostream>
#include <vector>
void f(std::vector<int> v) {std::cout <<__PRETTY_FUNCTION__ <<std::endl;}
void f(int n) {std::cout <<__PRETTY_FUNCTION__ <<std::endl;}
int main()
{
 f({42});//the int overload is being picked up
}

生活在Coliru上。

我有点惊讶地意识到,在这种情况下,正在获取int重载,换句话说,的输出是:

void f(int )

带着警告

警告:在标量初始值设定项 [-Wbraced-scalar-init] f ( {42} ) 周围有大括号;

当然,只有当我将 1-element 列表作为参数传递时,否则 std::vector 重载将被接收。

为什么 {42} 像一个标量一样对待,而不像一个init列表是否有强制编译器在 1-element 列表中选择 std::vector 重载( 不明确构造 std::vector<int>{42} )的方法?

PS: std::vector 具有一个初始化列表构造函数

vector(std::initializer_list<T> init, const Allocator& alloc = Allocator());

请参见 cppreference 中的( 7 ) 。

时间:原作者:0个回答

136 5

支撑初始值设定项没有类型,我们不能说 {42}int 或者 std::initializer_list<int>当用作参数时,重载解析for的特殊规则将应用于重载函数调用。

( 强调我的)

  • 否则参数类型不是类,初始值设定项列表为转换序列转换元素到参数类型需要付出

{42} 只有一个类型为 int的元素,因此它与重载 void f(int) 完全匹配。对于 void f(std::vector<int>),需要用户定义的转换。所以 void f(int) 在这里被接收。

是否有任何方法强制编译器选择 std::vector 重载( 即使在 1-element 列表中没有显式构建 std::vector<int>{42}) )?

作为 wordaround,你可以放置附加的大括号来强制编译器构造 std::initializer_list<int>,然后拾取 void f(std::vector<int>):

f({{42}});

LIVE

原作者:
...