C++ STL: поиск карты по итератору на другую карту
Вопрос
Я пытаюсь преодолеть некоторые препятствия и организовать данные особым образом.Я включаю упрощенный фрагмент кода, демонстрирующий мою боль.
Я не могу использовать усиление.Я использую последнюю версию 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;
}
Итак, как вы можете видеть, у меня есть одна простая карта, итератор для этой карты и еще одна карта, первый аргумент которой является итератором для первой карты.
Отсюда ясно:Почему я не могу поместить итератор на карту?Что я могу использовать итератор в качестве второго аргумента.Однако способ, показанный выше, обеспечивает следующее:
$ 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:map просто не позволяет этого?Я могу перекодировать свое приложение, чтобы обойти эту проблему, но это будет очень неэффективно, и я бы хотел, чтобы это работало.Есть ли другой вид указателя для элемента карты, который я мог бы использовать?
Спасибо за ваше время.
Решение
Вы не можете сделать это, потому что std::map
итераторы не являются итераторами с произвольным доступом, поэтому не сопоставимы с <
.
Вместо этого вы можете использовать указатели на value_type в первой карте в качестве ключа карты.
Другие советы
Вам придется научиться читать сообщения об ошибках.В частности, обратите внимание на сообщение, которое следует после многоречивого описания. где произошла ошибка:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_function.h:227: error: no match for 'operator<' in '__x < __y'
Итераторы карты не сравнимы с оператором «меньше», который карта использует по умолчанию.
Я предполагаю, что вы можете предоставить функцию сравнения, которая сравнивает пары, на которые указывает итератор, поскольку сами итераторы нельзя легко сравнить осмысленным образом.
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
)
map<Key, Value>
map
iterator
в качестве ключевого элемента в другом operator <
невозможно, поскольку Key
ожидает, что map iterator
будет определен по умолчанию для ключа. Если <=> (в данном случае <=>) не определено, вам нужно передать функтор в качестве функции предиката, обеспечивающей сравнение Key (итератор карты).