Search code examples
c++c++11c++14rvalue-reference

Rvalue reference behavior while returning from a function


In the below code:

class Myclass
{    
public:
    Myclass() = default;
    ~Myclass() = default;

    Myclass(Myclass&&) = default;
    Myclass& operator=(Myclass&&) = default;

    Myclass(const Myclass&) = delete;    
    Myclass& operator=(const Myclass&) = delete;
};

Myclass GetObj()
{
    Myclass obj;    
    return obj;
}

Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();

    return Wrapobj;
}

int main()
{
    return 0;
}

When it is compiled it gives error in function WrapperOfGetObj on return Wrapobj. Error is

'Myclass::Myclass(const Myclass &)': attempting to reference a deleted function

It means it is trying to call deleted copy constructor. As I know Wrapobj is lvalue and when it being returned its behavior should be same as obj in GetObj method i.e, calling move constructor at the time of return. Then why it is looking for copy constructor? What am I missing here?


Solution

  • The problem here is that (as T.C. wraps up in the comment section) Wrapobj is a reference, not an object, therefore implicit moving - i.e. treating the returned lvalue as an rvalue - does not apply in this case (see [class.copy]/32).

    You could fix this by writing:

    Myclass Wrapobj = GetObj();
    

    Instead of the current:

    Myclass&& Wrapobj = GetObj();
    

    Or by explicitly std::move()ing Wrapobj when returning it. I'd personally advise to go for the first option.