Std::unordered_map通过引用传递

std::unordered_map pass by reference

本文关键字:引用 map unordered Std      更新时间:2023-10-16

我通常用C编写代码,现在转向c++。我有一个有6000万个元素的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);
}

如果我只想传递pointer,如何像往常一样传递和查询:value = mer_map[key] ?我搜索并找到了passing by reference语法:

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

但似乎无法编译。请帮助。谢谢。

我猜你的问题是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];
}

要使用引用传递,你的函数应该声明为

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(

对于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