Question

J'essaie de franchir des obstacles pour organiser les données d'une manière particulière. J'inclus un morceau de code simplifié qui illustre ma douleur.

Je ne peux pas utiliser de boost. J'utilise la dernière version de g ++ dans cygwin.

#include <iostream>
#include <map>

using namespace std;

int main () {

    map< int,int > genmap;
    map< int,int >::iterator genmapit;
    map< map<int,int>::iterator,int > itermap;

    // insert something into genmap
    genmap.insert (make_pair(1,500) );

    // find and return iterator.
    genmapit=genmap.find(1);

    // insert the iterator/int into itermap. Dies on each of the following 3 versions of this line.
    //itermap[genmapit] = 600; // crash
    //itermap.insert ( pair< map<int,int>::iterator,int >(genmapit,600) ); // crash
    itermap.insert ( make_pair(genmapit,600) ); // crash

    return 0;
}

Comme vous pouvez le constater, j’ai une carte simple, un itérateur de cette carte et une autre carte contenant le premier argument en tant qu’itérateur de la première carte.

Cela ressort clairement de ceci: Pourquoi ne puis-je pas insérer d'itérateur dans la carte? Que je puisse avoir un itérateur comme deuxième argument. Cependant, la manière montrée ci-dessus fournit ceci:

$ make
g++    -c -o main.o main.cpp
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h: In member fun
ction `bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp =
 std::_Rb_tree_iterator<std::pair<const int, int> >]':
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_tree.h:871:   instantiate
d from `std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _All
oc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::i
nsert_unique(const _Val&) [with _Key = std::_Rb_tree_iterator<std::pair<const in
t, int> >, _Val = std::pair<const std::_Rb_tree_iterator<std::pair<const int, in
t> >, int>, _KeyOfValue = std::_Select1st<std::pair<const std::_Rb_tree_iterator
<std::pair<const int, int> >, int> >, _Compare = std::less<std::_Rb_tree_iterato
r<std::pair<const int, int> > >, _Alloc = std::allocator<std::pair<const std::_R
b_tree_iterator<std::pair<const int, int> >, int> >]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_map.h:360:   instantiated
 from `std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_
Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator, bool> std::
map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [wit
h _Key = std::_Rb_tree_iterator<std::pair<const int, int> >, _Tp = int, _Compare
 = std::less<std::_Rb_tree_iterator<std::pair<const int, int> > >, _Alloc = std:
:allocator<std::pair<const std::_Rb_tree_iterator<std::pair<const int, int> >, i
nt> >]'
main.cpp:23:   instantiated from here
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:227: error: no
 match for 'operator<' in '__x < __y'
make: *** [main.o] Error 1

" instancié à partir d’ici " ne me dit rien et une recherche sur le Web ne me donne aucune information à ce sujet.

Est-ce que STL: map ne permet tout simplement pas cela? Je peux recoder mon application pour contourner ce problème, mais ce sera très inefficace et j'aimerais que cela fonctionne. Existe-t-il un autre type de pointeur que je peux créer pour un élément de carte que je pourrais utiliser?

Merci de votre temps.

Était-ce utile?

La solution

Vous ne pouvez pas faire cela car std::map les itérateurs ne sont pas des itérateurs à accès aléatoire, ils ne sont donc pas comparables avec <.

Au lieu de cela, vous pouvez utiliser des pointeurs sur le type valeur (value_type) de la première carte en tant que clé de carte.

Autres conseils

Vous devez apprendre à lire les messages d'erreur. En particulier, regardez le message qui suit la longue description l'erreur est survenue:

  

/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:227: error: no match for 'operator<' in '__x < __y'

Les itérateurs de carte ne sont pas comparables avec les opérateurs inférieurs à ceux utilisés par défaut par la carte.

Je suppose que vous pouvez fournir une fonction de comparaison qui compare les paires pointées par l'itérateur, car les itérateurs eux-mêmes ne peuvent pas être facilement comparés de manière significative.

struct CompareIterator
{
     template <class FirstIter, class SecondIter>
     bool operator()(FirstIter lhv, SecondIter rhv) const
     {
         return *lhv < *rhv;
     }
};

//usage with map:
map< map<int,int>::iterator,int, CompareIterator > itermap;

std::pair définit operator<. J'ai également utilisé deux types d'itérateurs, car il est possible que les types soient différents (iterator et const_iterator)

map<Key, Value>

L'élément map iterator en tant qu'élément clé dans un autre operator < n'est pas possible car Key s'attend à ce que map iterator soit défini par défaut sur la clé. Si le <=> (dans ce cas <=>) n'est pas défini, vous devez passer un foncteur en tant que fonction de prédicat qui fournit la comparaison de Key (itérateur de carte).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top