C++ Scope – Getting a Reference Out of a Try Block

creferencescope

Using C++ I'd like to do something along the lines of:

  1. Try to get a reference to something in, say, a map
  2. If it throws, then return straight away
  3. Otherwise, go and use the reference

However because we can't declare a reference object without initialising in C++, then we can't do this directly.

For example if I was happy to pass by value, I could do:

std::map<char, int> mymap {...};
int x;
try {
    x = m.at('a');
} catch (out_of_range& e) {
    return;
}
// do something with x

However because I need a reference, I would have to do the following which won't compile.

std::map<char, int> mymap {...};
int& x;
try {
    x = m.at('a');
} catch (out_of_range& e) {
    return;
}
// do something with x

So the options I can see are (1), use a pointer, which I'd like to avoid, or (2), use a different map method which results in more verbose code, such as:

std::map<char, int> mymap {...};
auto x_it = m.find('a');
if (x_it == m.end()) {
    return;
}
int& x = x_it->second;
// do something with x

Are those the only options or, is there another way of doing this neatly?

Best Answer

The normal way is to move the "so something with x" line(s) also within the try block:

std::map<char, int> mymap {...};
try {
    int& x = mymap.at('a');
    // do something with x
} catch (out_of_range& e) {
    return;
}

The nice thing about exceptions is that when an exception is thrown, all code between the throw and catch locations is completely skipped over.
This means that you can write the code within the try { ... } catch block with the knowledge that everything has worked fine if you reach that line.

Related Topic