Почему вспомогательный инструмент для стирания-удаления-идиомы не предусмотрен стандартом?

Удаление элементов из коллекции в STL требует такой часто используемой техники, которая стала идиомой: стирание-удаление-идиома

Одним из наиболее распространенных способов использования этой идиомы является удаление элемента типа T из vector<T>

std::vector<Widget> widget_collection;
Widget widget;

widget_collection.erase(
std::remove(widget_collection.begin(), widget_collection.end(), widget),
widget_collection.end());

Это, очевидно, очень многословно, и нарушает СУХОЙ принцип — рассматриваемый вектор требуется 4 раза.

Итак, мой вопрос: почему стандарт не предоставляет вспомогательный инструмент?

Что-то вроде

widget_collection.erase_remove(widget);

или же

std::erase_remove(widget_collection, widget);

Это, очевидно, может быть распространено на

widget_collection.erase_remove_if(widget, pred);

так далее…

4

Решение

Эта проблема покрыта предложением N4009: равномерное стирание контейнера который говорит:

Это предложение добавить erase_if (container, pred), сделав его
легче устранить ненужные элементы правильно и эффективно.

[…]

Удивительно трудно удалить ненужные элементы из контейнера,
дан предикат, который отличает «плохие» элементы от «хороших» элементов.

Одной из основных сильных сторон STL является то, что все ее контейнеры имеют одинаковый
интерфейсы — у них много общих функций, и они следуют одному и тому же
конвенций. Когда контейнерные интерфейсы различаются, фундаментальные различия между
их структуры данных несут ответственность. Даже эти различия часто могут быть
игнорируется, благодаря дизайну алгоритма контейнера-итератора STL.

а также отмечает:

Правильный ответ
заключается в использовании идиомы стирания-удаления, которая неочевидна и должна преподаваться
вместо того, чтобы обнаружить (это называется «идиома» по причине).

Последняя версия N4273: равномерное стирание контейнера (редакция 2) похоже это было принят. Это часть Расширения для библиотечных основ V2 . Также см. Раздел cppreference для Стандартные библиотеки C ++, версия 2.

Головная ревизия (версия 6.0.0) gcc, доступный на Wandbox, имеет реализацию этого заголовка (увидеть это в прямом эфире):

#include <experimental/vector>
#include <iostream>

int main()
{
std::vector<int> v1 = {1,2,3,4,5,6} ;

std::experimental::erase_if( v1, [] (const int &x ) { return x < 4; } ) ;

for( const auto & v : v1 )
{
std::cout << v << ", " ;
}
std::cout << "\n" ;
}

Этот код также работает на WebCompiler что, кажется, подтверждает предположение T.C., что это также отправлено с MSVC 2015.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]