gaurav bharadwaj
gaurav bharadwaj

Reputation: 1771

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?

Upvotes: 3

Views: 204

Answers (1)

Andy Prowl
Andy Prowl

Reputation: 126432

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.

Upvotes: 6

Related Questions