Should foo be move-only?
Earlier today Vinnie Falco asked if I had an opinion on whether the Networking TS’s
CompletionCondition
concept should support “move-only” types. I said I don’t even
know what CompletionCondition
is, so how could I have an opinion on that? But then
it turned out that I did have an opinion.
The question “should my concept support move-only models?” is basically the same question
as “should my type-erased wrapper be able to wrap a move-only object?”
We’re familiar with the latter from std::function
versus
unique_function
.
There are two things to think about here.
First: If your thingie (concept or type-erased wrapper) needs to be copyable, or will be stored inside something that needs to be copyable, then clearly your thingie itself must be copyable. Example:
Should the
Comparator
parameter to astd::set
be copyable? Well, theset
object itself HAS-AComparator
, and theset
is copyable. When you copy aset
, you copy itsComparator
. SoComparator
must be copyable; so it must not support move-only models.
(Or else set
must be only conditionally copyable — that’s the other way out of the dilemma.
But, like any dilemma, there are only those two ways out.)
Second: So you’ve decided that your thingie doesn’t need to be copyable. Should you still require copyability?
Well, what part of the code gets simpler if you’re allowed to copy them? Think about what if my completion condition holds within itself a
std::string
member. I wouldn’t want you to copy that member more times than necessary, right? So is the number of “necessary” copies equal to zero? Then it needn’t be copyable.
That is, you should require copyability only if that requirement is going to make your life easier somehow. And then, even as you’re enjoying your easy life, you should still make sure to use move semantics wherever possible, so that you don’t end up wasting resources by expensively copying objects. If, at the end of your implementation, you realize that you only ever moved your thingies around — you never needed to copy them — well, then copyability is not needed by your algorithm. You probably shouldn’t require something that you don’t need.
Q.E.D.
Go on, ask me if Iterator
should be default-constructible…