复制构造函数调用捕获变量而不是移动构造函数

时间:2013-10-07 17:16:25

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

int main()
{
    A a;
    auto func = [a] {
    };

    auto newfunc = std::move(func);
    return 0;
}

将给出输出:

Copy ctor
Move ctor

这似乎是完全正常的。

但是,当A a;更改为const A a;时,输出如下:

Copy ctor
Copy ctor

为什么lambda的移动受原始变量是否为常量的影响?

FWIW,MSVC2012总是制作两份。

1 个答案:

答案 0 :(得分:0)

由于您的移动构造函数没有const A&&,因此不会调用它。由于移动通常将对象设置为默认值,因此通常无法从const对象移动。

请记住,如果移动构造函数正确重载,则移动对象。例如,尝试运行此版本的代码。

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

运行此代码,您会注意到对象是否移动了const资格。