Можете ли вы использовать `std:: remove_if` в контейнере` std:: unique_ptr`?
Учитывая std::vector<std::unique_ptr<SomeType> >
, можно ли использовать
remove_if
на нем? Другими словами, данный код:
std::vector<std::unique_ptr<SomeType> > v;
// fill v, all entries point to a valid instance of SomeType...
v.erase( std::remove_if( v.begin(), v.end(), someCondition ), v.end() );
я гарантирую после стирания, что все указатели, все еще находящиеся в v
, являются
действительный. Я знаю, что, учитывая интуитивную реализацию
std::remove_if
, и учитывая все реализации, на которые я смотрел,
Они будут. Я хотел бы знать, есть ли что-нибудь в стандарте
что гарантирует это; то есть, что std::remove_if
не разрешено копировать
любая из допустимых записей без повторного копирования копии в ее окончательный
место нахождения.
(Я, конечно, предполагаю, что условие не копируется.
условие имеет подпись типа:
struct Condition
{
bool operator()( std::unique_ptr<SomeType> ptr ) const;
};
то, конечно, все указатели будут недействительными после
remove_if
.)
Ответы
Ответ 1
25.3.8 в N3290 говорит о функции удаления:
Требуется: тип * сначала должен удовлетворять MoveAssignable требования (таблица 22).
и
Примечание: каждый элемент в диапазоне [ret, last), где ret - возвращаемый value, имеет действительное, но неопределенное состояние, поскольку алгоритмы могут исключить элементы путем замены или перемещения элементов, которые были первоначально в этом диапазоне.
Это означает, что это зависит от вашего оператора предиката. Поскольку ваш предикат не создает копию, элементы не копируются.
Ответ 2
Точно так же, как erase()
и resize()
, remove_if()
будут перемещать элементы (возможно, с помощью подкачки), поэтому элементы контейнера не нужно копировать. Нет ничего особенного в unique_ptr
, это просто другой тип только для перемещения.
Как вы указываете, предикат должен, конечно, принимать элементы по const-ссылке. Опять же, как и для любого подвижного типа.