Почему нет вспомогательных функций для set_union и т. Д., Которые принимают типы контейнеров вместо итераторов? - PullRequest
2 голосов
/ 08 июля 2011

std :: set_union и его родственники берут две пары итераторов для оперируемых множеств. Это здорово, потому что это самая гибкая вещь. Однако они очень легко могли бы создать дополнительные удобные функции, которые были бы более элегантными для 80% типичного использования.

Например:

template<typename ContainerType, typename OutputIterator>
OutputIterator set_union( const ContainerType & container1, 
                const ContainerType & container2, 
                OutputIterator      & result      )
{
    return std::set_union( container1.begin(), container1.end(), 
                           container2.begin(), container2.end(), 
                           result );
}

превратится:

std::set_union( mathStudents.begin(), mathStudents.end(), 
                physicsStudents.begin(), physicsStudents.end(), 
                students.begin() );

в

std::set_union( mathStudents, physicsStudents, students.begin() );

Итак:

  • Есть ли где-то такие удобные функции, которые я просто не нашел?

  • Если нет, то может ли кто-нибудь из причин, почему он был бы исключен из STL?

  • Возможно, в boost есть более полнофункциональная библиотека множеств? (Я не могу найти один)

Конечно, я всегда могу где-то поместить свои реализации в служебную библиотеку, но трудно организовать такие вещи так, чтобы они использовались во всех проектах, но не были конгломерированы неправильно.

Ответы [ 5 ]

8 голосов
/ 08 июля 2011

Есть ли где-то такие удобные функции, которые я просто не нашел?

Нет в стандартной библиотеке.

Если нет, то может ли кто-нибудь из причин, почему он будет исключен из STL?

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

Возможно, в boost есть более полнофункциональная библиотека множеств?

Boost.Range делает это.Конечно, Boost.Range делает больше , чем это.Это алгоритмы не принимают "контейнеры";они принимают диапазоны итераторов, для которых контейнеры STL удовлетворяют условиям.У них также есть ленивая оценка, которая может быть хорошей для работы.

2 голосов
/ 08 июля 2011

Одной из причин работы с итераторами, конечно, является то, что он носит более общий характер и работает с диапазонами, которые не являются контейнерами или просто частью контейнера.

Другая причина заключается в том, что подписи будут перепутаны,Многие алгоритмы, такие как std :: sort, уже имеют более одной подписи:

sort(Begin, End);
sort(Begin, End, Compare);

Где второй используется для пользовательского сравнения при сортировке по стандартному меньше чем.

Если мы теперь добавим набор sort для контейнеров, мы получим эти новые функции

sort(Container);
sort(Container, Compare);

Теперь у нас есть две сигнатуры sort(Begin, End) и sort(Container, Compare), которые оба принимают два параметра шаблона, и компиляторбудут проблемы с разрешением звонка.

Если мы изменим имя одной из функций для решения этой проблемы (sort_range, sort_container?), Это больше не будет удобным.

1 голос
/ 09 июля 2011

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

Я думаю, что есть историческая причина, которая, вероятно, помешала этому вообще когда-либо даже рассматриваться.

STL был введен в C ++ относительно поздно в процессе стандартизации.Вскоре после того, как это было принято, комитет проголосовал против даже рассмотрения любых новых функций для добавления в C ++ 98 (возможно, даже на том же заседании).К тому времени, когда большинство людей обернулось вокруг существующего STL, чтобы понять, насколько удобно вы можете получить что-то вроде диапазонов, а не отдельных итераторов, было уже слишком поздно, чтобы об этом даже говорили.

Даже еслиКомитет все еще рассматривал новые возможности, и кто-то написал предложение разрешить передачу контейнеров вместо дискретных итераторов и допустил неоднозначную реакцию, я подозреваю, что это предложение было бы отклонено.Многие (особенно C-ориентированные люди) видели STL как огромное дополнение к стандартной библиотеке в любом случае.Я вполне уверен, что немало людей сочли бы совершенно неприемлемым добавлять (много) больше функций / перегрузок / специализаций только для того, чтобы разрешить передачу одного параметра вместо двух.

1 голос
/ 08 июля 2011

Согласен, STL должен принимать контейнеры вместо пар итераторов по следующим причинам:

  • Более простой код
  • Алгоритмы могут быть перегружены для указанных контейнеров, т. Е. Могут использоватьалгоритм map :: find вместо std :: find -> более общий код
  • Поддиапазон может быть легко заключен в контейнер, как это делается в boost :: range
0 голосов
/ 08 июля 2011

Использование элементов begin & end для итерации позволяет использовать неконтейнерные типы в качестве входных данных. Например:

ContainerType students[10];
vector<ContainerType> physicsStudents;
std::set_union(physicsStudents.begin(), physicsStudents.end(), 
               &students[0], &students[10], 
               physicsStudents.begin());

Поскольку они являются такими простыми реализациями, я думаю, что имеет смысл не добавлять их в библиотеку std и разрешать авторам добавлять свои собственные. Особенно с учетом того, что они являются шаблонами, что потенциально увеличивает размер библиотеки для кода и добавление вспомогательных функций в std приведет к раздуванию кода.

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