C++11 为捕获的变量调用了复制构造函数,而不是移动构造函数
使用gcc 4.7.2或4.8.1编译时,运行以下程序C++11 为捕获的变量调用了复制构造函数,而不是移动构造函数,c++11,lambda,move-semantics,C++11,Lambda,Move Semantics,使用gcc 4.7.2或4.8.1编译时,运行以下程序 #include <stdio.h> #include <functional> class A { public: A() { } A(const A& a) { printf("Copy ctor\n"); } A(A&& a) { printf("Move ctor\n"); } }
#include <stdio.h>
#include <functional>
class A
{
public:
A()
{
}
A(const A& a)
{
printf("Copy ctor\n");
}
A(A&& a)
{
printf("Move ctor\n");
}
};
int main()
{
A a;
auto func = [a] {
};
auto newfunc = std::move(func);
return 0;
}
这似乎很正常
但是,;更改为常量A;,结果如下:
Copy ctor
Copy ctor
为什么lambda的移动会受到原始变量是否为常量的影响
FWIW,MSVC2012始终制作两个副本。因为您的移动构造函数没有常量a&&它将不会被调用。由于移动通常将对象设置为其默认值,因此通常无法从常量对象移动
请记住,如果move构造函数正确重载,那么对象将被移动。例如,尝试运行此版本的代码
#include <stdio.h>
#include <functional>
class A
{
public:
A()
{
}
A(const A& a)
{
printf("Copy ctor\n");
}
A(const A&& a)
{
printf("Move ctor\n");
}
};
int main()
{
const A a;
auto func = [a] {
};
const auto newfunc = std::move(func);
return 0;
}
运行此代码,您会注意到无论是否存在常量限定,对象都会移动。常量不能自动删除。通过添加它,捕获lambda必须将其存储为const,并且您不能从const中移动。@FrançoisMoisan这很接近,但并不完全正确,正如您从我的示例中看到的,您可以使用const A&&@aaronman重载移动构造函数您当然是对的。不知怎的,我认为签名要求非常量值引用是特别的。@FrançoisMoisan你是正确的,因为从常量对象移动本来就是奇怪的,因为你不能从常量对象中移动任何东西谢谢,今天我学习了常量值引用:-但我的问题是:变量的常量是否和lambda中变量的类型有关?@OlegAndreev它必须存储在正确的地方,当然,如果你真的想知道的话,你会对兰姆爸爸有更多的了解implementation@OlegAndreev顺便说一句,我知道你没有足够的支持率,但如果我的回答对你有帮助,你仍然可以接受
#include <stdio.h>
#include <functional>
class A
{
public:
A()
{
}
A(const A& a)
{
printf("Copy ctor\n");
}
A(const A&& a)
{
printf("Move ctor\n");
}
};
int main()
{
const A a;
auto func = [a] {
};
const auto newfunc = std::move(func);
return 0;
}