这只是一个理论问题。当我执行此代码时:
#include <functional>
#include <cstdio>
struct A {
int value = 100;
A() {
printf("A\n");
}
A(const A& a) {
printf("copy A\n");
}
~A() {
printf("~A\n");
}
};
void function(std::function<int()> lambda) {
printf("%d\n", lambda());
}
int main()
{
A a;
auto lambda = [a]() -> int {
return a.value;
};
function(lambda);
return 0;
}
输出是这样的:
A
copy A
copy A
copy A
100
~A
~A
~A
~A
我的问题是为什么结构A被复制3次而不是2次? 一个副本采用lambda捕获,第二个采用传递参数到函数,第三个采用什么?
答案 0 :(得分:2)
如果您按如下方式更改代码,您将看到相同数量的复制操作:
int main()
{
A a;
auto&& lambda = [a]() -> int {
return a.value;
};
std::function<int()>{lambda};
}
创建lambda时会发生第一次复制/移动构造。第二个和第三个复制/移动构造在构造 std :: function 期间发生。根据N3690, std :: function 使用的构造函数如下所示:
template <class F> function(F);
这意味着,在将参数传递给构造函数时,传递的参数将被复制/移动一次。在构造函数中,它将被另一次复制/移动以进行类型擦除。
如果构造函数使用引用(例如使用完美转发),则只能看到两个复制/移动构造。但是,我不知道为什么在这种情况下没有使用它。
template <typename Arg> function(Arg&&);