mercredi 26 juillet 2017

move constructor called on return instead of copy

Today I found that this code doesn't work as I expect it to work. According to my knowledg for L-values copy constructor should be called while for R-values it should choose move constructor. Otherwise what's the purpose of std::move which actually does nothing but casts to R-value. I was expecting that return obj will call copy constructor, but it calls move. I understand that copy is useless here, but that's about rules. What if my copy constructor has a side effect and that's my case (I know that it shouldn't, but technically it can - for example here: std::cout call). Is there anything in standard that allows such behavior? Also how can I force a copy?

#include <iostream>

class X
{
public:
    X() = default;

    X(const X& r): i(r.i)
    {
        std::cout << "copy ctor" << std::endl;
    }

    X(const X&& r): i(r.i)
    {
        std::cout << "move ctor" << std::endl;
    }
    int i = 0;
};

X foo()
{
    X obj;
    obj.i = 10;
    return obj;
}

int main()
{
    X x = foo();
}

move ctor

move ctor

Aucun commentaire:

Enregistrer un commentaire