Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no std::move_if algorithm?

Tags:

c++

c++17

I've seen a few places on the internet where they describe using std::copy_if with std::make_move_iterator, but if the iterator were to be a forward iterator, that would result in having valid but unspecified (VBU) objects scattered around the source container.

Wouldn't it be better to have a std::move_if algorithm such that if an object is moved, then it would move the resulting VBU object to the end of the range, like that which is done in the std::remove_if algorithm, consolidating all of the VBU objects together so that they can be erased or reassigned?

like image 887
Adrian Avatar asked Apr 03 '19 19:04

Adrian


1 Answers

If move_if existed as an algorithm, it would have to be specified as:

template <class InputIt, class OutputIt, class UnaryPredicate>
OutputIt move_if(InputIt first, InputIt last, OutputIt d_first, UnaryPredicate pred)
{
    return std::copy_if(std::make_move_iterator(first), std::make_move_iterator(last),
        d_first, pred);
}

We are very used to thinking of the difference between copying and moving as simply a matter of whether or not we care about the source object. We still do? Copy. We don't? Move. Having move_if(f, l, d, pred) do something semantically different than copy_if(f, l, d, pred) seems inherently confusing and error-prone - since the inevitable usage of it would be to do a "copy where we don't care about the source anymore."

But then - you're more or less describing the problems with this algorithm in your question. When would I use this? I would end up with a source range where some of the elements are moved-from but others aren't. What could I do with such a range? I couldn't coalesce them somehow since I don't know which ones they are or anything. Moving those elements to the back is useful - and we do have that algorithm: remove_if.

Basically the only thing I could do with the source range at this point is destroy it. Maybe that's useful. Maybe that's useful enough to even merit this algorithm in std::. I don't know. But move_if definitely needs to do the same thing as copy_if.

like image 84
Barry Avatar answered Oct 19 '22 04:10

Barry