代码之家  ›  专栏  ›  技术社区  ›  Travis

C++ STL:由迭代器映射到另一个映射

  •  2
  • Travis  · 技术社区  · 15 年前

    我正试图通过一些特殊的方式来组织数据。我包含了一段简单的代码来演示我的痛苦。

    我不能用助推器。 我在cygwin中使用了最新版本的g++。

    #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;
    }
    

    如你所见,我有一个简单的映射,一个到那个映射的迭代器,还有一个映射,它有第一个参数作为到第一个映射的迭代器。

    很明显: Why can't I put an iterator in map? 我可以用迭代器作为第二个参数。但是,上面所示的方法提供了这一点:

    $ 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不允许这样做吗?我可以重新编码我的应用程序来解决这个问题,但它将非常低效,我想让这个工作。是否还有其他类型的指针可以用于我可以使用的映射元素?

    谢谢你抽出时间。

    3 回复  |  直到 15 年前
        1
  •  4
  •   CB Bailey    15 年前

    你不能这样做,因为 std::map 迭代器不是随机访问迭代器,因此无法与 < .

    相反,您可以使用指向第一个映射中的值类型的指针作为映射键。

        2
  •  3
  •   UncleBens    15 年前

    你必须学会阅读错误信息。特别要注意在冗长的描述之后出现的消息 哪里 发生错误:

    /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 )

        3
  •  0
  •   aJ.    15 年前
    map<Key, Value>
    

    这个 map iterator 作为另一个元素的关键元素 地图 不可能,因为 地图 期待 operator < 默认为键。如果 Key (在这种情况下) map iterator )如果没有定义,则需要将函数作为提供键比较的谓词函数(映射迭代器)传递。