14

In the code show below, how do I assign rvalue to an object A in function main?

#include <iostream>

using namespace std;

class A
{
    public:
        int* x;
        A(int arg) : x(new int(arg)) { cout << "ctor" << endl;}
        A(const A& RVal) { 
            x = new int(*RVal.x);
            cout << "copy ctor" << endl;
        }
        A(A&& RVal) { 
            this->x = new int(*RVal.x);
            cout << "move ctor" << endl;
        }
        ~A()
        {
            delete x;
        }
};

int main()
{
    A a(8);
    A b = a;
    A&& c = A(4); // it does not call move ctor? why?
    cin.ignore();
    return 0;
}

Thanks.

Abbas
  • 6,720
  • 4
  • 35
  • 49
codekiddy
  • 5,897
  • 9
  • 50
  • 80

1 Answers1

20

Any named instance is l-value.

Examples of code with move constructor:

void foo(A&& value) 
{
   A b(std::move(value)); //move ctr
}

int main()
{
    A c(5); // ctor
    A cc(std::move(c)); // move ctor
    foo(A(4)); 
}
alexm
  • 6,854
  • 20
  • 24
  • A c(A(4)); does not call move ctor, why not? it call's copy ctor. why? thanks for response! – codekiddy Jan 05 '12 at 09:24
  • It calls just the constructor here: http://ideone.com/2Arx3 (The compiler is free to eliminate redundant constructor calls - copy or move.) – visitor Jan 05 '12 at 09:42
  • 2
    `A c(factory());` is not perfect forwarding, it's copy elision/RVO. – Cat Plus Plus Jan 05 '12 at 09:47
  • @Cat Plus Plus thanks for the correction. I modified the code to perform the perfect forwarding – alexm Jan 05 '12 at 10:12
  • 1
    Well, actually, it's still not correct. If you want to perfect forward the argument to the constructor, it should be `template A factory(T&& val) { return A(std::forward(val)); }`. But there's still RVO involved, so I'm not sure if it's beneficial to include that to illustrate move ctors at all. – Cat Plus Plus Jan 05 '12 at 10:34
  • 1
    Oh, I know. `void foo(movable_type); foo(movable_type());` should invoke move ctor without explicit `std::move`. And for explicit move `A moved_from; A moved_to(std::move(moved_from));` is enough. And no need for introducing perfect forwarding and reference collapsing rules. – Cat Plus Plus Jan 05 '12 at 10:36