From [12.8] [11] of N3337:
The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. [ N
It's handled by the specification of class member access expressions. The key part is
Let
x
be either the parameter of the constructor or, for the move constructor, an xvalue referring to the parameter.
In other words, a defaulted move constructor for
struct X { int x, &y; };
does the equivalent of
X::X(X&& other) : x(std::move(other).x), y(std::move(other).y) {}
The important thing here is that the result of a class member access expression x.m
, where m
names a non-static data member, is always an lvalue if m
has reference type, but an xvalue if x
is an rvalue and m
has non-reference type. (See [expr.ref]/4.) This ensures that lvalue reference members will be initialized with lvalues.