Reputation: 8074
Copy-assignment for a class with a reference member variable is a no-no because you can't reassign the reference. But what about move-assignment? I tried simply move
ing it but, of course, that destroys the source object when I just want to move the reference itself:
class C
{
public:
C(X& x) : x_(x) {}
C(C&& other) : x_(std::move(other.x_)) {}
C& operator=(C&& other)
{
x_ = std::move(other.x_);
}
private:
X& x_;
};
X y;
C c1(y);
X z;
C c2(z);
c2 = c1; // destroys y as well as z
Should I just not be implementing move-assignment and sticking with move-construction only? That makes swap(C&, C&)
hard to implement.
Upvotes: 30
Views: 12705
Reputation: 275310
A reference is, in some sense, a T *const
with syntactic sugar on top to auto-derefence, auto-capture, and auto-lifetime extend temporaries. (note that this is not quite true, but often is in practice and practicality)
If you want a reseatable reference, C++ has those: they are called pointers. You can use an accessor to replace dereferencing with a function call if you like. The remaining feature (temporary lifetime extension) that is hard to emulate does not apply to struct
members.
Upvotes: 2
Reputation: 1057
(Posted as an answer from comment as suggested by the OP)
In general if one wants to do non-trivial stuff with references in C++, one would be using reference_wrapper<T>
, which is essentially a fancy value-semantic stand-in for a T&
, then one would be done with it - it already provides (re)assignment and other operations. I'm sure that would make move constructor and assignment near-trivial, if not trivial (note not trivial
as in per the is_trivially_*
semantics).
"Reference wrapper" is added to C++03 as part of TR1, and is part of C++11.
Documentation: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
Upvotes: 31