Lambda 作为 std::vector::emplace_back 的参数
Lambda as an argument to std::vector::emplace_back
我遇到了将 lambda 作为参数传递给 emplace_back 的代码,这让我很困惑。所以我写了一个小测试来验证这样的语法:
struct A
{
int a;
A(){cout<<"constructed"<<endl;}
A(const A& other){a = other.a; cout<<"copied"<<endl;}
A(const A&& other){a = other.a; cout<<"moved"<<endl;}
};
int main()
{
vector<A> vec;
vec.emplace_back(
[]{A a;
a.a = 1;
return a;
}());
A a2;
a2.a = 2;
vec.emplace_back(std::move(a2));
return 0;
}
我有两个问题:
1) 有人可以阐明如何将 lambda 作为参数传递给 emplace_back 吗?过去我只看到构造函数参数被传递给 emplace。
2) 输出为:
constructed
moved
constructed
moved
copied
最后一份副本来自哪里?为什么这两种方法不等价。
注意 lambda 定义后的 ()
,它调用 lambda。此代码等效于以下内容:
int main()
{
auto make_a = []()
{
A a;
a.a = 1;
return a;
};
vector<A> vec;
vec.emplace_back(make_a());
// ...
}
其中,由于 lambda 有空捕获,等同于:
A make_a()
{
A a;
a.a = 1;
return a;
}
int main()
{
vector<A> vec;
vec.emplace_back(make_a());
// ...
}
Can someone clarify how a lambda can be passed as an argument to emplace_back?
您没有传递 lambda。相反,您传递了调用 lambda 的 result。
Where is the last copied coming from?
它来自向量。当a2
插入到vec
时,会发生重新分配,重新分配内存,将旧内存中的对象复制到新内存
如果将移动构造函数指定为noexcept
,即
A(const A&& other) noexcept {a = other.a; cout<<"moved"<<endl;}
然后std::vector
会在重新分配时移动对象而不是复制,你可以看到最后的复制变成了移动。
我遇到了将 lambda 作为参数传递给 emplace_back 的代码,这让我很困惑。所以我写了一个小测试来验证这样的语法:
struct A
{
int a;
A(){cout<<"constructed"<<endl;}
A(const A& other){a = other.a; cout<<"copied"<<endl;}
A(const A&& other){a = other.a; cout<<"moved"<<endl;}
};
int main()
{
vector<A> vec;
vec.emplace_back(
[]{A a;
a.a = 1;
return a;
}());
A a2;
a2.a = 2;
vec.emplace_back(std::move(a2));
return 0;
}
我有两个问题: 1) 有人可以阐明如何将 lambda 作为参数传递给 emplace_back 吗?过去我只看到构造函数参数被传递给 emplace。 2) 输出为:
constructed
moved
constructed
moved
copied
最后一份副本来自哪里?为什么这两种方法不等价。
注意 lambda 定义后的 ()
,它调用 lambda。此代码等效于以下内容:
int main()
{
auto make_a = []()
{
A a;
a.a = 1;
return a;
};
vector<A> vec;
vec.emplace_back(make_a());
// ...
}
其中,由于 lambda 有空捕获,等同于:
A make_a()
{
A a;
a.a = 1;
return a;
}
int main()
{
vector<A> vec;
vec.emplace_back(make_a());
// ...
}
Can someone clarify how a lambda can be passed as an argument to emplace_back?
您没有传递 lambda。相反,您传递了调用 lambda 的 result。
Where is the last copied coming from?
它来自向量。当a2
插入到vec
时,会发生重新分配,重新分配内存,将旧内存中的对象复制到新内存
如果将移动构造函数指定为noexcept
,即
A(const A&& other) noexcept {a = other.a; cout<<"moved"<<endl;}
然后std::vector
会在重新分配时移动对象而不是复制,你可以看到最后的复制变成了移动。