carte, lambda, remove_if
Donc, j'ai problème avec std::map, lambda et stl algorithme(remove_if). En fait, le même code avec std::list ou std::vector fonctionne bien.
Mon test exemple :
#include <map>
#include <iostream>
#include <algorithm>
struct Foo
{
Foo() : _id(0) {}
Foo(int id) : _id(id)
{
}
int _id;
};
typedef std::map<int, Foo> FooMap;
int main()
{
FooMap m;
for (int i = 0; i < 10; ++i)
m[i + 100] = Foo(i);
int removeId = 6;
//<<< Error here >>>
std::remove_if(m.begin(), m.end(), [=](const FooMap::value_type & item) { return item.second._id == removeId ;} );
for (auto & item : m )
std::cout << item.first << " = " << item.second._id << "\n";
return 0;
}
Message d'erreur :
In file included from /usr/include/c++/4.6/utility:71:0,
from /usr/include/c++/4.6/algorithm:61,
from main.cxx:1:
/usr/include/c++/4.6/bits/stl_pair.h: In member function ‘std::pair<_T1, _T2>& std::pair<_T1, _T2>::operator=(std::pair<_T1, _T2>&&) [with _T1 = const int, _T2 = Foo, std::pair<_T1, _T2> = std::pair<const int, Foo>]’:
/usr/include/c++/4.6/bits/stl_algo.h:1149:13: instantiated from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = std::_Rb_tree_iterator<std::pair<const int, Foo> >, _Predicate = main()::<lambda(const value_type&)>]’
main.cxx:33:114: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:156:2: error: assignment of read-only member ‘std::pair<const int, Foo>::first’
Je ne comprends pas quel est le problème ici. Donc, je suis heureux de lire quelques-uns des conseils ou des orientations à ce sujet. Mon objectif - utiliser les nouvelles lambda de style avec des std::map et les algorithmes, comme remove_if.
g++ 4.6, -std=c++0x.
source d'informationauteur Reddy
Vous devez vous connecter pour publier un commentaire.
Le problème est que
std::map<K,V>::value_type
eststd::pair<const K, V>
aka.first
estconst
et non cessible. Les Lambdas n'ont rien à voir avec le problème ici.std::remove_if
"supprime" les éléments en déplaçant les éléments du conteneur, ainsi que tout ce qui ne rentre pas le prédicat est à l'avant, avant le retour de l'itérateur. Tout ce qui suit itérateur n'est pas spécifié. Il le fait avec une simple affectation, et puisque vous ne pouvez pas attribuer à unconst
variable, vous obtenez cette erreur.†Le nom
remove
peut être un peu trompeuse et, dans ce cas, vous voulez vraimenterase_if
mais hélas, qui n'existe pas. Vous avez à faire avec une itération sur tous les éléments et de les effacer à la main aveccarte.erase(iterator)
:C'est sûr, parce que vous pouvez effacer chacun des nœuds de l'arbre sans les autres itérateurs arriver invalidé. Notez que je n'ai pas d'incrément de la variable d'itération de la boucle for en-tête lui-même, car ce serait ignorer un élément dans le cas où vous effacez un nœud.
† A présent, vous devriez avoir remarqué que ce serait faire des ravages dans le
std::map
's de la commande, qui est la raison pour laquelle la clé estconst
- de sorte que vous ne pouvez pas influencer la commande en aucune façon après un article a été inséré.Vous pouvez utiliser les trouver et de les effacer de la carte. Ce n'est pas aussi pratique que remove_if, mais il pourrait être le meilleur que vous avez.