1

When compiled with gcc 4.7.2 or 4.8.1 and run the following program

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

will give the output:

Copy ctor
Move ctor

which seems to be perfectly normal.

However, when A a; is changed to const A a;, the output is as follows:

Copy ctor
Copy ctor

Why is the move of lambda affected by the fact whether the original variable has been const or not?

FWIW, MSVC2012 always makes two copies.

Oleg Andreev
  • 353
  • 1
  • 9
  • constness can't be dropped automatically. By adding it, the capturing lambda must store it as const and you can't move from const. – François Moisan Oct 07 '13 at 17:36
  • @FrançoisMoisan that's close but not exactly correct, as you can see from my example you can overload the move constructor with `const A&&` – aaronman Oct 07 '13 at 18:06
  • @aaronman You are right of course. I somehow thought the signature asked for non-const rvalue-references specfically. – François Moisan Oct 07 '13 at 18:41
  • @FrançoisMoisan you are correct in the sense that moving from a const object is inherently weird because you can't "move" anything out of the const object – aaronman Oct 07 '13 at 18:45

1 Answers1

0

Since you do not have a const A&& for your move constructor it will not be called. Since a move generally sets an object to it's default value you often cannot move from a const object.

Keep in mind a if the move constructor is overloaded correctly the object will be moved. For example try running this version of your code.

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

Run this code and you will noticed that the object is moved wether there is a const qualification or not.

aaronman
  • 18,343
  • 7
  • 63
  • 78
  • Thank you, today I learned about const rvalue references :-) But my question is: does the constness of the `a` variable concern the type of variable inside lambda? – Oleg Andreev Oct 07 '13 at 18:23
  • @OlegAndreev well it has to be stored somewhere right, of course to really know you would have so know a bit more about lamb dad implementation – aaronman Oct 07 '13 at 18:31
  • @OlegAndreev btw I know you don't have enough rep to upvote but if my answer helped you, you can still accept it – aaronman Oct 07 '13 at 18:43