4

I usually code in C. Now moving to C++. I have a std::unordered_map with 60 million entries. It is loaded once only and would not be modified later. I would like to pass it to some functions from time to time. But this code would copy the hash map every time:

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); } 

If I want to pass the pointer only, how to pass it and query it as usual: value = mer_map[key]? I searched and find the passing by reference syntax:

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

But it seems cannot compiled. Please help. Thanks.

3
  • Using a reference would be a good C++ approach. Show the error you're getting. Commented Apr 4, 2013 at 15:39
  • Why not just pass a non-const reference? Commented Apr 4, 2013 at 15:40
  • Yes, I tried the not-const method suggested by @juanchopanza as well, it also works. Thanks. Commented Apr 4, 2013 at 16:58

3 Answers 3

14

I am guessing your problem is that operator[] is non const, because it adds a default constructed element when accessed with a key that isn't already in the map. You can use at(), which assumes the key is present and throws an exception otherwise:

typedef unordered_map<uint64_t, mer*> mer_map; void foo(const mer_map& m) { mer* val = m.at(key); } 

or use 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; } } 

Note: You could also bypass the problem by passing a non-const reference, but by doing so you are saying the function would modify the map. You should only use a non-const reference if you really intend to modify an object.

void foo(mer_map& m) { mer* val = m[key]; } 
Sign up to request clarification or add additional context in comments.

Comments

3

To use pass by reference your functions should be declared like

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); } 

This will work normal for the access operator

mer_map[key] 

and to access member functions something like

mer_map.find( 

To pass a pointer they should be of the form

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); } 

However in the pointer version to use the access operator you have to dereference the pointer first.

(*mer_map)[key] 

and to access member functions something like

kmers->find( 

Comments

0

For map and unordered_map the index operator [] is non-const because calling it with an index that doesn't exist will cause that element to be created. You use at() if you don't want to create the element. Then you can use const reference to map or unordered_map. Be aware that at() will throw if the element does not exist.

You can use an iterator to test for existence:

bool esists(const mer_map& kmers, uint64_t i) { unordered_map<uint64_t, mer*::const_iterator it = kmers.find(i); return it != kmers.end(); } 

Or you could just access mer_maps through iterators in your code.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.