Почему [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
через неконстантный итератор).