C ++ STL: поиск карты итератором для другой карты - PullRequest
2 голосов
/ 28 октября 2009

Я пытаюсь прыгнуть через несколько обручей, чтобы организовать данные особым образом. Я включил упрощенный кусок кода, который демонстрирует мою боль.

Я не могу использовать повышение. Я использую последнюю версию G ++ в 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;
}

Итак, как вы можете видеть, у меня есть 1 простая карта, итератор этой карты и другая карта, в которой первый аргумент используется в качестве итератора для первой карты.

Это ясно из этого: Почему я не могу поместить итератор в карту? Что у меня может быть итератор в качестве второго аргумента. Однако способ, показанный выше, обеспечивает это:

$ 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

«экземпляр отсюда» ничего не говорит мне, а поиск в Интернете не дает мне никакой информации об этом.

STL: карта просто не допускает этого? Я могу перекодировать свое приложение, чтобы обойти это, но оно будет очень неэффективным, и я хотел бы, чтобы это работало. Можно ли использовать указатель другого типа для элемента карты, который я мог бы использовать?

Спасибо за ваше время.

Ответы [ 3 ]

4 голосов
/ 28 октября 2009

Вы не можете сделать это, потому что std::map итераторы не являются итераторами с произвольным доступом, поэтому не сопоставимы с <.

Вместо этого вы можете использовать указатели на тип_значения на первой карте в качестве ключа карты.

3 голосов
/ 28 октября 2009

Вы должны научиться читать сообщения об ошибках. В частности, посмотрите на сообщение, которое приходит после длинного описания , где произошла ошибка:

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

Итераторы карты несопоставимы с оператором less-than, который карта использует по умолчанию.

Полагаю, вы можете предоставить функцию сравнения, которая сравнивает пары, на которые указывает итератор, поскольку сами итераторы не могут быть легко сопоставлены осмысленным образом.

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 определяет operator<. Я также использовал два типа итераторов, поскольку возможно, что типы различаются (iterator и const_iterator)

0 голосов
/ 28 октября 2009
map<Key, Value>

map iterator как элемент ключа в другом map невозможен, поскольку map ожидает, что operator < будет определено по умолчанию для ключа. Если Key (в данном случае map iterator) не определено, то вам нужно передать функтор в качестве функции предиката, которая обеспечивает сравнение Key (итератор карты).

...