Syntactic sugar or a useful feature? More than just sweet sweet sugar baby! This little known feature is a nice way of wrapping an entire function in a
try
catch
block. So instead of writing this:
void eat_it()
{
try
{
throw runtime_error("System error from eat_it()");
}
catch(exception& e)
{
cout << "Swallowing: " << e.what() << endl;
}
}
You can write this:
void eat_it_sugar() try
{
throw runtime_error("System error from eat_it_sugar()");
}
catch(exception& e)
{
cout << "Swallowing: " << e.what() << endl;
}
The meaning of the two functions is identical. Notice here that I’m swallowing the exception instead of propagating it out. I could call...
throw
...to re-throw it, or in both cases, I could throw a different exception inside the...
catch
...block.
The caveat is with function try
-catch
blocks around constructors: they have to re-throw the same or different exception. If you don’t re-throw explicitly, the compiler will do it for you. It is also useful for catching exceptions emitted during the initialization of member variables, and throwing something else (or re-throwing the same). Like this:
struct P
{
P() { throw logic_error("Logic error from P::P()"); }
};
struct Q
{
Q() try : m_P()
{
cout << "Never printed!" << endl;
}
catch(exception& e)
{
cout << "Inside Q::Q() caught: " << e.what() << endl;
throw runtime_error("Runtime error from Q::Q()");
}
P m_P;
};
Complete listing (try_block.cpp):
#include <iostream>
#include <stdexcept>
using namespace std;
struct P
{
P() { throw logic_error("Logic error from P::P()"); }
};
struct Q
{
Q() try : m_P()
{
cout << "Never printed!" << endl;
}
catch(exception& e)
{
cout << "Inside Q::Q() caught: " << e.what() << endl;
throw runtime_error("Runtime error from Q::Q()");
}
P m_P;
};
void eat_it()
{
try
{
throw runtime_error("System error from eat_it()");
}
catch(exception& e)
{
cout << "Swallowing: " << e.what() << endl;
}
}
void eat_it_sugar() try
{
throw runtime_error("System error from eat_it_sugar()");
}
catch(exception& e)
{
cout << "Swallowing: " << e.what() << endl;
}
int main() try
{
eat_it();
eat_it_sugar();
Q q;
}
catch(exception& e)
{
cout << "Inside main() caught: " << e.what() << endl;
}
Program output:
Swallowing: System error from eat_it()
Swallowing: System error from eat_it_sugar()
Inside Q::Q() caught: Logic error from P::P()
Inside main() caught: Runtime error from Q::Q()