I can't think of a reason the sole trait of having a reference or const member or not would imply that the class should have either of these traits (noncopyable or unmovable)
I think the premise is wrong.
Having a const
data member or a reference data member does not make the class non-copyable: it simply makes it impossible to assign it or move from it in a destructive way.
That is because a destructive move operation is not sound for const
objects or references: it would be against their semantics, since the state of a const
object shall never be altered, and references cannot be unbound.
However, the fact that X
is not copy-assignable or move-assignable does not compromise the possibility of constructing copies of those objects, which is - as you point out - a sound operation. The following program, for instance, will compile fine:
struct X
{
X() : x(0), rx(x) { }
const int x;
const int& rx;
};
int main()
{
X x;
X x1 = x; // Copy-initialization (copy-constructs x1 from x)
X x2 = X(); // Copy-initialization (copy-constructs x2 from a temporary)
}
The compiler will generate a copy-constructor implicitly for you, and moves will degenerate to copies. If this degeneration of move into copy is inappropriate for the semantics of your class, then you may consider not having const
or reference members.