为什么此代码无效?
auto foo=[](){
return {1,2};
};
但是,这是有效的,因为initializer list
仅用于初始化vector
不返回自身:
auto foo=[]()->std::vector<int>{
return {1,2};
};
为什么我无法退回initializer list
?它可能很有用。例如,一个lambda可用于初始化vector
或list
或......以及某些默认值。
答案 0 :(得分:25)
Lambda返回类型推导使用auto
规则,通常会推导std::initializer_list
就好了。但是,语言设计者在return语句中禁止从支撑的初始化列表中进行演绎([dcl.spec.auto] / 7):
如果扣除是针对
return
语句而且初始化程序是a braced-init-list ([dcl.init.list]),该程序格式不正确。
原因是std::initializer_list
具有引用语义([dcl.init.list]/6)。 []() -> std::initializer_list<int> { return {1, 2}; }
与[]() -> const int & { return 1; }
一样糟糕。当lambda返回时,initializer_list
对象的后备数组的生命周期结束,并且留下一个悬空指针(或两个)。
Demo:
#include <vector>
struct Noisy {
Noisy() { __builtin_printf("%s\n", __PRETTY_FUNCTION__); }
Noisy(const Noisy&) { __builtin_printf("%s\n", __PRETTY_FUNCTION__); }
~Noisy() { __builtin_printf("%s\n", __PRETTY_FUNCTION__); }
};
int main()
{
auto foo = []() -> std::initializer_list<Noisy> { return {Noisy{}, Noisy{}}; };
std::vector<Noisy> bar{foo()};
}
输出:
Noisy::Noisy()
Noisy::Noisy()
Noisy::~Noisy()
Noisy::~Noisy()
Noisy::Noisy(const Noisy&)
Noisy::Noisy(const Noisy&)
Noisy::~Noisy()
Noisy::~Noisy()
注意在到目前为止创建的所有Noisy
对象已经被销毁之后如何调用复制构造函数。
答案 1 :(得分:5)
std::initializer_list
无法通过模板参数推断出来,这意味着您必须告诉lambda它是明确的:
#include <initializer_list>
#include <iostream>
#include <vector>
int main()
{
auto foo = []() -> std::initializer_list<int> { return {1, 2}; };
std::vector<int> bar{foo()};
for (int x : bar) { std::cout << x << " "; };
}
Demo。以下是initializer list proposal:
背后的基本原理初始化列表可以用作模板参数吗?考虑一下:
template<class T> void f(const T&); f({ }); // error f({1}); f({1,2,3,4,5,6}); f({1,2.0}); // error f(X{1,2.0}); // ok: T is X
最后一次通话显然没有问题(假设 X {1,2.0} 本身有效)
因为模板参数是 X 。因为我们没有引入任意的清单 类型(产品类型),我们不能将 T 推断为 {int,double} f({1,2.0}),以便电话是 一个错误。普通{}没有类型,因此 f({})也是一个错误。这留下了同类列表。应该接受 f({1})和 f({1,2,3,4,5,6})吗?如果是的话,
有什么意义?如果是这样,答案必须是推导出的类型 T 是
的 initializer_list 即可。除非有人提出至少一个好用的这个简单的 功能(类型 E 的同类列表推断为 initializer_list ),我们不会提出它,所有示例都会出错:没有模板
参数可以从(不合格的)初始化列表中推导出来。谨慎的一个原因是 这是我们可以想象有人对可能的解释感到困惑 单元素列表。例如, f({1})可以调用 f&lt; int&gt;(1)吗?不,那将是
非常不一致。
答案 2 :(得分:1)