C++11 为捕获的变量调用了复制构造函数,而不是移动构造函数

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"); } }

使用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");
    }
};

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;                                                                      
}