3

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?

1
  • You need to use std::move() to make an rvalue explicitly. Commented Oct 14, 2016 at 7:50

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

12 Comments

this might be good extra reading for this topic.
The expression Wrapobj is an lvalue of type MyClass; expressions never have reference type (after the [expr]/5 adjustment). The problem is that the implicit move only applies to objects of automatic storage duration ([class.copy]/32), and a reference is not an object. Moreover, "named lvalues in a return statement won't be treated as rvalues by the compiler if their type is different from the return type of the function" is incorrect since CWG 1579.
@T.C.: Has that been clarified in the Standard? Back in the day when I was more active I used to be convinced of that, but then I figured it was probably up to interpretation (see Scott's blog post). Is there a final word? Anyway I'll try to reword it more precisely.
I don't think it's very useful to consider the pre-adjustment type when it vanishes instantly (hence the parenthesized qualifier).
@T.C.: I wrote a separate question
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.