C++ 在C+;中创建字符串到字符串向量的哈希映射的最佳方法是什么+;?

C++ 在C+;中创建字符串到字符串向量的哈希映射的最佳方法是什么+;?,c++,C++,条件,不希望在所有位置创建对象的副本。 应快速、高效且不会造成泄漏。 应该是线程安全的 理想情况下,我希望在HashMap中存储指向向量的指针,但我担心这样会导致内存泄漏 这是最好的方式吗 std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap; std::映射邻接映射; 这样做很明智 我能提供的唯一建议是避免将自动ptr放入STL容器中。 如果您使用sha

条件,不希望在所有位置创建对象的副本。 应快速、高效且不会造成泄漏。 应该是线程安全的

理想情况下,我希望在HashMap中存储指向向量的指针,但我担心这样会导致内存泄漏

这是最好的方式吗

std::map<std::string, std::auto_ptr<std::vector<std::string> > > adjacencyMap;
std::映射邻接映射;

这样做很明智

我能提供的唯一建议是避免将自动ptr放入STL容器中。

如果您使用shared_ptr,一切都会正常工作。

禁止在任何标准容器中存储
自动ptr
。§23.1/3:“存储在这些组件中的对象类型必须符合可复制的要求
类型(20.1.3),以及可分配类型的附加要求。“
std::auto_ptr
不满足该要求。

如果使用C++0x,请使用
唯一的_ptr
。如果不是,请使用
boost::shared_ptr

std::map不是作为哈希映射实现的,而是作为红黑树实现的(请参阅)

对于c++0x编译器,可以使用std::无序_映射;对于非c++0x编译器,可以使用std::tr1::无序_映射

Boost也有它的功能。

那么

map<string, vector<string> >
map
请注意,map非常特别,因为它与vector不同,在调整map大小期间,或者在插入或删除其他元素时,从不复制元素。因此,不需要使用指针来防止不必要的深度拷贝

发件人:

Map有一个重要的属性,即在Map中插入新元素不会使指向现有元素的迭代器无效。从Map中删除元素也不会使任何迭代器无效,当然,对于实际指向正在删除的元素的迭代器除外

当然,如果您没有就地构造值,并且出于某种原因需要将其复制出去,那么将值复制到映射中可能会有一个深度复制,但通常很容易就地完成所有操作,可能是使用帮助器ala:

vector<string>& this_one = my_map[my_key];
// work on this_one
vector&this_one=my_map[my_key];
//做这个

关于线程安全标准:在非常见情况下,没有一个STL容器保证线程安全。在某些情况下,您可以使用某些并发访问模式,但我怀疑您是否能够使用哈希映射实现这一点

如果这确实是您所需要的,那么您将需要一个线程安全散列映射类。英特尔有一个
concurrent\u hash\u map
class IIRC,这对我来说似乎是最明显的选择,尽管我确信还有其他选择


尽管请注意,这当然不会使向量线程安全,但只会使包含的hashmap;如果你也需要的话,TBB也有一个并发向量。

那么多问题捆绑在一起

  • 散列映射:
    std::无序映射
    std::tr1::无序映射
    boost::无序映射
    都是散列映射。它们是可靠的,但不是线程安全的(见下文)
  • 性能:存储纯
    向量
    ,您将避免内存泄漏,在即将推出的C++0x中,它们很可能会被移动而不是复制,因此您将获得性能和安全性。。。同时,在分析告诉您瓶颈在哪里之前,不要担心性能
  • 线程安全:有一个线程安全的容器是非常无用的,因为你很可能想要线程安全的操作
  • 解释后一点:假设我有一个很棒的
    tbb::concurrent\u hash\u map
    名为
    container

    • 线程1
      if(!container.empty())
    • 线程2
      container.clear()
    • 线程1
      {value=container.front();}//未定义的行为
    问题在于线程安全容器不能保证线程的正确性。您仍然需要为您的操作显式地锁定容器,因此,将容器锁定在您的锁中是没有意义的


    因此,不要太担心寻找线程安全的容器,STL没有任何线程安全容器的原因是它几乎毫无用处,因为您需要的大多数操作都是复合的,并且需要为整个套件持有锁,它们之间没有发布。

    请记住,std::map不是散列映射,而是排序映射(大多数编译器将其实现为二叉树)。哈希映射(std::unordered_映射)将成为下一版本标准的一部分。您的编译器可能已经包含了它。如果没有,Boost有一个。C++0x何时可用?建议使用it生产代码吗?您的评论让我意识到为什么我从来不想要线程安全的容器(或者为什么我用Java编程时它们总是被窃听)