10

这个问题可能有点粗略,因为我家里没有可用的代码,但我知道这件事否则会困扰我整个周末。

当我尝试将一些代码更新为 C++11 时,我开始std::mapstd::unordered_map. 该代码仅用于std::map::find()访问地图中的特定元素,因此我认为替换应该很容易。返回的迭代器存储在一个auto-typed 变量 ( auto res = map.find( x ),所以打字应该检查正常。但是,当使用我访问存储的元素时,res->second.do_stuff()我得到一个编译器错误,告诉我,struct std::pair<char, B> does not have a member second。现在这真的让我很困惑,但不幸的是我没有有时间进一步调查。

也许这是足够的信息,所以有人可以给我一个关于这个奇怪的编译器错误的提示。或者我的理解是除了需要订购的部分之外应该具有相同的界面,不正确std::mapstd::unordered_map

编辑

正如这里所承诺的,对这个问题进行了更多的分析。这很可能会让有人现在更好地帮助我。正如我从评论中的提示中猜测的那样,这并不是真正由我访问地图中的元素的点引起的,而是由代码的其他部分引起的。我发现的原因是,我使用 X 类中的映射来存储指向 X 类其他元素的指针(一种树结构)。然而,这似乎适用于std::map但不适用于std::unordered_map. 这是一些非常简单的代码,它显示了这个问题:

#include <stdint.h>
#include <unordered_map>
#include <map>

class Test {
  std::map<uint32_t, Test> m_map1; // Works
  std::unordered_map<uint32_t, Test> m_map; // gives error: ‘std::pair<_T1, _T2>::second’ has incomplete type
};

int main() {
  return 1;
}

std::map工作std::unordered_map不工作。任何想法为什么会这样,或者可以做些什么来让它与 a 一起工作std::unordered_map

4

2 回答 2

16

我猜想因为 std::unordered_map 需要重新散列,因此需要复制元素,所以类型需要是完整的,而只使用指向元素的指针的映射不会出现这个问题。

这里的解决方案是有一个指向指针的无序映射:

std::unordered_map<uint32_t, std::shared_ptr<Test> >. 
于 2011-12-13T09:52:38.850 回答
12

使用不完整类型mapunordered_map不完整类型涉及未定义行为:

特别是,在以下情况下效果是不确定的:

[...]

— 如果在实例化模板组件时将不完整类型 (3.9) 用作模板参数,除非该组件特别允许。

于 2011-12-14T09:27:37.420 回答