std::unordered_map 传递引用

4

我通常使用C语言编程。现在要转向C++。我有一个包含六千万条目的std::unordered_map。它只会被加载一次,以后不会被修改。我想偶尔将它传递给一些函数。但是这段代码会每次复制哈希映射:

typedef unordered_map<uint64_t, mer*> mer_map;
void test_pass_by_ref3(mer_map kmers) {
}

void test_pass_by_ref2(mer_map kmers) {
    test_pass_by_ref3(kmers);
}

void test_pass_by_ref(mer_map kmers) {
    test_pass_by_ref2(kmers);
}

如果我只想传递指针,然后像平常一样查询它:value = mer_map [key],该怎么做?我搜索并找到了“按引用传递”的语法:

void foo(const ClassName &name)
{
    ClassName& temp = const_cast<ClassName&>(name);
    ... ....
}

但似乎无法编译。请帮忙看看。谢谢。

使用引用是一个好的 C++ 方法。展示你得到的错误。 - Drew Dormann
为什么不直接传递一个非const引用? - David G
是的,我也尝试了@juanchopanza建议的非const方法,它也可以工作。谢谢。 - Joy
3个回答

14

我猜测您的问题是operator[]不是const,因为当使用一个不存在于映射中的键访问时,它会添加一个默认构造的元素。 您可以使用at(),它假定该键存在,否则会抛出异常:

typedef unordered_map<uint64_t, mer*> mer_map;

void foo(const mer_map& m)
{
  mer* val = m.at(key);
}

或者使用std::unordered_map::find()

void foo(const mer_map& m)
{
  auto it = m.find(key);
  if (it != m.end())
  {
    // element is in map, use it
    mer* val = it->second;
  }
}

注意:你也可以通过传递一个非const引用来避开这个问题,但这样做意味着函数将修改地图。只有当你真的想要修改对象时,才应该使用非const引用。

void foo(mer_map& m)
{
  mer* val = m[key];
}

3
为了使用按引用传递,您的函数声明应该像这样:
typedef unordered_map<uint64_t, mer*> mer_map;
void test_pass_by_ref3(mer_map& kmers) {
}

void test_pass_by_ref2(mer_map& kmers) {
    test_pass_by_ref3(kmers);
}

void test_pass_by_ref(mer_map& kmers) {
    test_pass_by_ref2(kmers);
}

这将对访问操作符正常工作。
mer_map[key]

要访问成员函数可以这样做:

mer_map.find(

要传递指针,它们应该采用以下格式:
typedef unordered_map<uint64_t, mer*> mer_map;
void test_pass_by_poi3(mer_map *kmers) {
}

void test_pass_by_ref2(mer_map *kmers) {
    test_pass_by_poi3(kmers);
}

void test_pass_by_ref(mer_map *kmers) {
    test_pass_by_poi2(kmers);
} 

然而,在指针版本中,要使用访问运算符,您必须先取消引用指针。
(*mer_map)[key]

访问成员函数可以使用类似以下的语法:

kmers->find(

0
对于 mapunordered_map,索引操作符 [] 是非 const 的,因为使用不存在的索引调用它将导致该元素被创建。如果您不想创建该元素,则可以使用 at()。然后,您可以使用 mapunordered_map 的 const 引用。请注意,如果元素不存在,at() 将抛出异常。
您可以使用迭代器来测试元素是否存在:
bool
esists(const mer_map& kmers, uint64_t i)
{
  unordered_map<uint64_t, mer*::const_iterator it = kmers.find(i);
  return it != kmers.end();
}

或者你可以直接通过代码中的迭代器访问mer_maps。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接