std :: unordered_map按引用传递

时间:2013-04-04 15:37:12

标签: c++

我通常用C编写代码。现在转向C ++。我有一个std::unordered_map,有6000万条目。它只加载一次,以后不会被修改。我想不时将它传递给某些功能。但是这段代码每次都会复制哈希映射:

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);
    ... ....
}
但似乎无法编译。请帮忙。感谢。

3 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:2)

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

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(

答案 2 :(得分: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。