Alex Rivera | Logout

Can we return objects having a deleted/private copy/move constructor by value from a function?

Asked 2011-10-28T22:46:39.747
21

In C++03 it is impossible to return an object of a class having a private non-defined copy constructor by value:

struct A { A(int x) { ... } private: A(A const&); };

A f() {
  return A(10); // error!
  return 10;    // error too!
}

I was wondering, was this restriction lifted in C++11, making it possible to write functions having a class type return type for classes without constructors used for copy or move? I remember it could be useful to allow callers of a function use the newly returned object, but that they are not able to copy the value and store it somewhere.

Edit
Report

1 Answer

2

I was wondering, was this restriction lifted in C++11?

How could it be? By returning something by value, you are by definition copying (or moving) it. And while C++ can allow that copy/move to be elided in certain circumstances, it's still copying (or moving) by the specification.

I remember it could be useful to allow callers of a function use the returned object, but that they are not able to copy the value and store it somewhere.

Yes. You get rid of the copy constructor/assignment, but allow the value to be moved. std::unique_ptr does this.

You can return a unique_ptr by value. But in doing so, you are returning an "prvalue": a temporary that is being destroyed. Therefore, if you have a function g as such:

std::unique_ptr<SomeType> g() {...}

You can do this:

std::unique_ptr<SomeType> value = g();

But not this:

std::unique_ptr<SomeType> value1 = g();
std::unique_ptr<SomeType> value2 = g();
value1 = value 2;

But this is possible:

std::unique_ptr<SomeType> value = g();
value = g();

The second line invokes the move assignment operator on value. It will delete the old pointer and move the new pointer into it, leaving the old value empty.

In this way, you can ensure that the contents of any unique_ptr is only ever stored in one place. You can't stop them from referencing it in multiple places (via pointers to unique_ptr or whatever), but there will be at most one location in memory where the actual pointer is stored.

Removing both the copy and move constructors creates an immobile object. Where it is created is where it's values stay, forever. Movement allows you to ha

answered 2011-10-28T23:08:42.647

Your Answer