4

A coworker and I are debating whether const or reference members are ever the right thing to do. const and reference members make a class noncopyable and unmovable unless you write your own copy and move operators which ignore the reference or const members. I can't find a case where ignoring copying or moving certain members just because they are references or const makes sense.

I think having an unmovable object is very rarely logically sound, and is a choice that only has something to do with whether the class is location invariant. A noncopyable object is much more common, but the choice to make a class noncopyable has to do with whether it holds a resource which is logically noncopyable, if it represents sole ownership, etc. 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)

Should they ever be used? Should one but not the other? What are examples?

Community
  • 1
  • 1
David
  • 27,652
  • 18
  • 89
  • 138
  • 1
    I don't think they make the class noncopyable or unmovable; it cannot be copied/moved *into,* but it can certainly be copied/moved *from.* It's more like "unassignable" than "noncopyable." – Angew is no longer proud of SO May 01 '13 at 13:16
  • 1
    I've found reference members to be quite useful for things like function objects. – Vaughn Cato May 01 '13 at 13:27
  • 1
    Curious statement about the unmovable objects. I would say that there is _usually_ no reason to make an object movable. Entity objects, of course, should never be movable, since they never occur as temporaries. And making objects with value semantics movable is an optimization which doesn't necessarily apply to many types, and means a significant loss of portability (at least today), and added complexity. In fact, I'd argue that movable should only be used when the profiler says you need it. – James Kanze May 01 '13 at 13:35
  • I second Vaughn Cato's statement. – Anon Mail May 01 '13 at 13:45

1 Answers1

5

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.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451