9

Since C++11, to move append some vector y to another vector x, you can do:

x.insert(x.end(), std::make_move_iterator(y.begin()), std::make_move_iterator(y.end()));

With C++17 class template argument deduction it is possible to write this a bit more concisely:

x.insert(x.end(), std::move_iterator(y.begin()), std::move_iterator(y.end()));

From C++17 onwards, would that not make std::make_move_iterator redundant? Is there still some value in having std::make_move_iterator()?

Evg
  • 25,259
  • 5
  • 41
  • 83
Ton van den Heuvel
  • 10,157
  • 6
  • 43
  • 82
  • 1
    I don't have a definitive answer, but I am under the impression that *all* standard argument-deducing `make_gizmo` factory functions are made redundant by class template argument deduction. – Quentin Sep 02 '19 at 20:03
  • 1
    @Quentin: No, they're not. `make_shared` is *always* useful, as it can allocate both the object and the control block in the same storage, which you can't do otherwise. And for things like `make_unique`, it was the change to order of expression evaluation in C++17 that made it unnecessary, not class template deduction. – Nicol Bolas Sep 02 '19 at 20:28
  • @NicolBolas these two are not about deducing arguments though, in fact they both have a non-deduced one :) – Quentin Sep 02 '19 at 21:03
  • 3
    @Quentin None of `make_tuple`, `make_pair`, `make_reverse_iterator`, `make_optional`, etc., are redundant. – Barry Sep 02 '19 at 21:11
  • @Barry looks like I did well to question myself there. – Quentin Sep 02 '19 at 21:15
  • @Quentin Cunningham's Law :-) – Barry Sep 02 '19 at 21:32

1 Answers1

10

Yes. One of the motivations for class template argument deduction was to avoid having to write these kinds of factory functions. In the case of move_iterator, CTAD completely subsumed the factory function. Not only does it give you all the same behavior, but it actually does one better - if the iterator you're passing in is already a move_iterator, CTAD won't give you double-wrapping whereas the factory function would.

However, there is still going to be a lot of code that uses the factory function... so removing it would be a breaking change. But it's just obsolete, its continued existence doesn't cause anybody harm. It may eventually be deprecated.


Note that while it is true in this case that CTAD subsumes the factory function, that is not true in the general case as the two options may have different functionality. It's not even true for all the iterator adaptors. For std::reverse_iterator(r), if r is already a reverse_iterator, will just give you a copy of r... whereas std::make_reverse_iterator(r) will re-reverse the iterator (effectively giving you back a forward iterator).

Barry
  • 286,269
  • 29
  • 621
  • 977