Why does std::reference_wrapper explicitly define a copy assignment operator?

Viewed 716

A std::reference_wrapper explicitly declares the copy assignment operator. Why? This should prevent move construction/assignment from being implicitly defined so my assumption is that they do not want you to move a std::reference_wrapper, but I am not sure why that would matter.

If you look at the "possible implementation", they just default the operator: https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D

Just looking for some history on why the committee felt the need for this.

4 Answers

This should prevent move construction/assignment from being implicitly defined

std::reference_wrapper is a non-owning reference (a pointer, really), move operation is no different from copy. Don't confuse it with std::shared_ptr.

std::reference_wrapper is an object with reference-like semantics. But unlike built in references, a reference_wrapper can be re-bound, copied and moved. This allows it it to be used in standard containers. So I do not understand your confusion, by its design a reference_wrapper is supposed to be copyable and movable.

They declare it because it has work to do.

Yes, this inhibits an automatically-generated move constructor. No, that doesn't matter. The authors would have had to define their own anyway (for the same reason they need to create a copy constructor), except that there is no use in "moving" something that doesn't own a resource. It would be the same as a copy.

That doesn't mean that a std::reference_wrapper isn't movable, it just means that "moving" one is the same as copying it. And there's no point in implementing that twice!

Consider what state you would expect the moved-from std::reference_wrapper to be in. You don't want to have a reference wrapper referring to something that doesn't exist if you can help it

Related