Почему [std::unique] не может применяться к [std::multiset]?

#include <set>
#include <algorithm>

using namespace std;

int main()
{
        multiset<int> coll{ 1, 1, 2 };
        unique(coll.begin(), coll.end()); // error
}

Почему не могу std::unique применить к std::multiset?

3 ответа

Решение

Потому что std::unique изменяет (смещая) элементы в диапазоне [first, last), переданные при назначении перемещения. Это означает, что тип итератора с разыменованным типом должен соответствовать требованиям MoveAssignable.

Требования к типу

  • ForwardIt должен соответствовать требованиям ForwardIterator.
  • Тип разыменованного ForwardIt должен соответствовать требованиям MoveAssignable.

Но итератор std::multiset является константным итератором (начиная с C++11), который не соответствует требованию. Защищенный элемент не может быть перемещен через них.

std::multiset это внутренне отсортированный контейнер, std::unique меняет элементы мест в контейнере. std::unique использует container::iterator_type в его реализации и в связи с тем, что структура std::multiset строгое, оно имеет только const_iterator_type, Следовательно std::unique не может быть применен к std::multiset тип.

До с ++11 была введена внутренняя структура std::multimap можно изменить, так std::unique может быть нанесен на такой контейнер.

std::unique не удаляет повторяющиеся значения из диапазона. Вместо этого он перемещает их в конец диапазона (путем замены двух элементов во входной последовательности). В std::multiset и другие ассоциативные контейнеры, порядок элементов определяется предикатом сортировки и не может быть изменен пользователем. Это ограничение достигается созданием неконстантного итератора std::multiset несколько похоже на его const_iterator (т.е. вы не можете изменить элемент std::multiset через неконстантный итератор).

Другие вопросы по тегам