Search code examples
c++exceptionboostinitialization-list

workarounds for BOOST_THROW_EXCEPTION's missing ternary operator in initialization lists


I often end up using ternaries that throw exceptions which may seem a bit weird but save the day in initialization lists (hence that helps for writing sound constructors, hence that helps for RAII, ...). E.g. if the argument a is a smart_ptr<> that we want non nullptr, then I could initiate a member like

member(a ? a->get_something() : throw exception())

I think this is a valid, legit & safe use (do tell me if this is not).

I recently switched to boost::exception, and unfortunately condition ? ret_value : BOOST_THROW_EXCEPTION(exception()) doesn't compile (since the compiler cannot reify typeof(ret_value) and void).

Are there any work-arounds better than creating a whole new private static method and putting an if inside?


Solution

  • This is perfectly valid C++, but many compilers won't see BOOST_THROW_EXCEPTION as a throw-expression, but just a regular void-type expression. As the standard requires that either the void-type expression is a throw expression, or both branches are of type void, the compiler rejects the ternary expression.

    The typical workaround is to use the comma operator:

    condition ? ret_value : (BOOST_THROW_EXCEPTION(exception()), decltype(ret_value){})
    

    You can, of course, replace the part after the comma with any expression of the correct type, and you can be certain that it won't be used.