Он сказал, что он хотел использовать erase- удалить идиомы, так вот возможный способ, с помощью функции объекта:
struct Unifier{
set<int> foundElements;
bool operator()(int & a){
if(foundElements.find(a) != foundElements.end()){
return true;
}else{
foundElements.insert(a);
return false;
}
}
};
int main(){
list<int> v;
v.push_back(5);
v.push_back(4);
v.push_back(5);
v.push_back(3);
v.push_back(5);
v.push_back(3);
copy (v.begin(), v.end(), ostream_iterator<int>(cout," "));
Unifier u;
v.remove_if(u);
cout << endl << "After:" << endl;
copy (v.begin(), v.end(), ostream_iterator<int>(cout," "));
}
Обновление: Приведенный выше код имеет тонкую ошибку. Согласно C++ 11 [algorithms.general]/10
:
[Примечание: если не указано иное, алгоритмы, которые принимают функциональные объекты в качестве аргументов, могут свободно копировать эти функциональные объекты. Программисты, для которых важна идентичность объекта, должны рассмотреть возможность использования класса-оболочки, который указывает на объект неготовности реализации, такой как reference_wrapper<T>
(20.8.3) или какое-то эквивалентное решение. -end примечание]
Там нет, как представляется, нет «не указано иное» для std::list::remove_if
, так что этот код может не удалить все дубликаты, так как он может создавать копии предиката в начале, а затем использовать различные копии одного предикат для разных частей списка. Example of this actually happening for std::remove_if.
Простое исправление для C++ 11 должен заменить v.remove_if(u)
с:
v.remove_if(reference_wrapper<decltype(u)>(u));
В C++ 03 Я не уверен, если выше цитата присутствовал; но если бы это было тогда, исправление заключалось бы в том, чтобы сделать foundElements
статическим или для рефакторирования Unifier
, чтобы все его копии ссылались на один экземпляр foundElements
.
Link to related question
Ну, очевидно, вы могли бы вызвать 'l.sort()' перед вызовом 'l.unique()', но я предполагаю, что должна быть причина, почему вы не можете этого сделать? :) – hrnt
Не уверен в алгоритмах STL, но очевидный способ сделать это - выполнить итерацию по списку, создав хэш-набор: если каждый элемент не в наборе, он уникален, поэтому добавьте его в set; если он находится в наборе, это дубликат, поэтому удалите его из списка. – Rup
Почему бы вам не предложить нам какой-нибудь ваш код? –