【问题标题】:Insert order std::map插入订单 std::map
【发布时间】:2011-11-26 17:04:02
【问题描述】:

我会创建一个关联数组(如 std::map),它按插入顺序存储元素。我写了这个类:

template <typename K, typename V>
class My_Map : public std::unordered_map<K,V>
{
 public:
 V& operator[]( const K&& key )
  {
    typename std::unordered_map<K,V>::iterator __i = find(key);
    if (__i == std::unordered_map<K,V>::end()) //se non l'ho trovato...
    {
      __i = insert(__i, std::make_pair(std::move(key), V()) );
      mHistory.push_back(__i);std::cout<<"Sto inserendo: "<<key<<std::endl;
    }
    return (*__i).second;
  }

  typename std::unordered_map<K,V>::iterator cbegin() const
  {
        return *mHistory.cbegin();
  }

  typename std::unordered_map<K,V>::iterator cend() const
  {
      return *mHistory.cend();
  }

  private:
    std::list<typename std::unordered_map<K,V>::iterator> mHistory;
};

using namespace std;

int main()
{
    My_Map<string,int> myMap;


    myMap["1"] = 1;
    myMap["23"] = 23;
    myMap["-3"] = 3;
    myMap["23"] = 28;
    myMap["last element"] = 33;

    for (auto x = myMap.cbegin(); x != myMap.cend(); ++x)//{std::cout<<"sn dentro\n";}
        cout<<(*x).first <<"\t"<<x->second<<endl;
}

我使用 unordered_map 代替 std::map 因为 std::map 在我插入新元素时混合了迭代器。

此代码有一个问题:main() 中的 for 因分段错误而失败。使用 cbegin() 和 cend() 传递的迭代器无效...为什么?怎么了?

【问题讨论】:

  • 查看 Boost.multi_index,这正是您的建议。
  • MCT中也有链接地图。
  • 强烈建议不要从像您这样的容器派生(它们没有虚拟析构函数),并且带有前导下划线的变量名通常被认为是为编译器和标准库保留的。我可能是错的,但我很确定无序映射不能确保插入顺序,如果你想要你可以使用 std::pair 的 std::vector 但是你将无法通过键语义访问作为关联数组,如那些在 PHP 或其他的。
  • 11111:下划线+大写字母或双下划线由实现保留,标准是这样说的,它们不是“通常认为”保留的。它们是,不要使用它们。
  • @11111: 他的班级有一个 std::list 来保存(并遍历)插入顺序。

标签: c++ c++11


【解决方案1】:

第一件事是你不能取消引用列表的结束迭代器。其次,我也怀疑yourMap.cend 是否一定可以从yourMap.cbegin 访问。

看起来您可能需要一个用于列表迭代器的适配器,该适配器会自动取消引用存储的 map iterator 指向映射项的指针。

在任何情况下,您都需要遍历列表,而不是从 unordered_map 中的随机点到其中的另一个随机点。


另外:添加元素可能会导致重新散列,这将使迭代器无效(但不会导致元素的指针或引用)。您甚至不应该将迭代器存储到 unordered_map 中。

【讨论】:

  • 有一种方法可以在不使用 boost_multiindex 的情况下解决这个问题,使用相同的 std::map 插入语法? (myMap[myKey] = myValue;)
猜你喜欢
  • 1970-01-01
  • 2010-09-10
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 2011-05-30
相关资源
最近更新 更多