[英]Forcing std::vector overload instead of int overload on list with one element
考虑下面的代码:
#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
}
我很惊讶地意识到在这种情况下会接收到int重载,即程序的输出为:
无效f(int)
带有警告
警告:标量初始值设定项[-Wbraced-scalar-init] f({42})括起来;
当然,只有当我将一个1元素列表作为参数传递时,才会发生这种情况,否则将拾取std::vector
重载。
为什么{42}
被视为标量而不是初始化列表? 有没有办法强迫编译器选择std::vector
重载(而没有显式构造std::vector<int>{42}
)甚至在1元素列表上?
PS: std::vector
具有init-list构造函数
vector(std::initializer_list<T> init, const Allocator& alloc = Allocator());
请参阅cppreference中的 (7)。
大括号初始化器没有类型,我们不能说{42}
是int
或std::initializer_list<int>
。 当用作参数时, 重载解析的特殊规则将应用于重载的函数调用。
(强调我的)
- 否则,如果参数类型不是类,并且初始值设定项列表包含一个元素 ,则隐式转换序列是将元素转换为参数类型所需的序列
{42}
仅具有一个类型为int
元素,则它与重载void f(int)
完全匹配。 对于void f(std::vector<int>)
需要用户定义的转换。 因此, void f(int)
将在此处拾取。
有没有办法强迫编译器选择
std::vector
重载(而无需显式构造std::vector<int>{42})
甚至在1元素列表上?
可以用一个大括号将编译器构造为std::initializer_list<int>
,然后选择void f(std::vector<int>)
:
f({{42}});
强制std :: vector重载
int main()
{
f(std::vector<int>{42}); // the vector overload is being picked up now
}
为什么不选择vector(initializer_list)
构造函数?
假设另一个标头声明一个void f(std::set<int> v)
。
您希望编译器在面对f({1})
时如何作出反应:构造vector
或构造set
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.