Можете ли вы использовать `std :: remove_if` для контейнера` std :: unique_ptr`? - PullRequest
13 голосов
/ 07 декабря 2011

Учитывая 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.)

Ответы [ 2 ]

5 голосов
/ 07 декабря 2011

Так же, как erase() и resize(), remove_if() будет перемещать элементы (возможно, путем замены), поэтому элементы контейнера не должны быть копируемыми. В unique_ptr нет ничего особенного, это просто еще один тип движения.

Как вы указали, предикат, конечно, должен принимать элементы по константной ссылке. Опять же, как для любого подвижного типа.

2 голосов
/ 07 декабря 2011

25.3.8 в N3290 говорит о функции удаления:

Требуется: Тип * first должен удовлетворять требованиям MoveAssignable (Таблица 22).

и

Примечание: каждый элемент в диапазоне [ret, last), где ret - это возвращаемое значение, имеет допустимое, но неопределенное состояние, поскольку алгоритмы могут исключать элементы путем замены или перехода от элементов, которыеизначально были в этом диапазоне.

Это означает, что это зависит от вашего оператора предиката.Поскольку ваш предикат не создает копию, элементы копироваться не будут.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...