I have a class Data
which is (as for now) non-copyable. std::sort
on std::vector<Data>
works because I have defined move-constructor and move-assignment for Data
. I do it this way because the class has a lot of data inside and copying the contents would be too slow. However, I am considering now adding a copy constructor Data(const Data& other)
and standard assignment operator (from const Data&
) to the class, for unrelated reasons. How can I make sure that when I sort a vector of Data
, std::sort
will still use the move-constructor and move-assignment?
Asked
Active
Viewed 3,530 times
7

quant_dev
- 6,181
- 1
- 34
- 57
-
2Did you try it? You might be surprised at the results. – Sam Varshavchik Jan 10 '16 at 00:03
-
1See also: http://stackoverflow.com/questions/14212701/stdsort-does-not-always-call-stdswap – Sam Varshavchik Jan 10 '16 at 00:20
-
5If you do make the class copyable and moveable both, you should declare the move constructor `noexcept` (assuming it is). Doesn't affect `sort` performance, but it will make a difference when adding elements to the `vector` because of its strong exception guarantee. – Praetorian Jan 10 '16 at 00:44
-
@Praetorian If class `T` has a `noexcept` move constructor, will `std::vector
` have a `noexcept` move constructor too? – quant_dev Jan 10 '16 at 00:48 -
3@quant_dev: Those are not related. Vector's move constructor moves its buffer, not individual T instances (note: the small buffer optimization is not valid for std::vector). – Cheers and hth. - Alf Jan 10 '16 at 00:50
-
1"How can I make sure": just for a test, you can add `throw` or `abort` to your copy constructor/assignment and check that sorting does not hit it. Or you can declare **but not define** them and check that it still links. Keeping tests for it long term, when you will actually be using copies in other parts of the code, seems painful and unnecessary. – Marc Glisse Jan 10 '16 at 08:00
-
I ended up not declaring them and adding a `copy` function, to make it clear that normally the `Data` objects are moved, not copied. – quant_dev Jan 11 '16 at 07:56
2 Answers
4
How can I make sure that when I sort a vector of Data, std::sort will still use the move-constructor and move-assignment?
Actually, you don't need to. You have to make sure that the swap
function used exploits directly or indirectly any trick already used in the move constructor. That is I think how it works. In other words, sort
needs a good swap, not necessarily a copy.
Where "directly" could mean simply using the default std::swap
that uses the move constructor when it can.
template <class T> void swap (T& a, T& b)
{
T c(std::move(a)); a=std::move(b); b=std::move(c);
}
So, chances are, you don't need to do anything special because swap
(or as @MarcGlisse noted, the sort algorithm directly) will use the move constructor.

alfC
- 14,261
- 4
- 67
- 118
-
3`sort` is not specified to use only `swap`. If you look at actual implementations, they also use move constructors and move assignments. – Marc Glisse Jan 10 '16 at 07:57
-
1@MarcGlisse, probably right and depends on the implementation I guess. In either case the OP shouldn't worry. – alfC Jan 10 '16 at 08:06
3
Just provide move-constructor, move-assignment and free swap
-function (in the same namespace) for your Data
class

Victor Dyachenko
- 1,363
- 8
- 18