Exception constraints

By , last updated December 16, 2019

Exception constraints check if an expression E is marked noexcept, and returns true only if it evaluates to noexcept(true).

Not sure what noexcept is? It is a new keyword from C++11 and is used to mark methods whether they are allowed to throw exceptions or not. If a method is not allowed to throw exceptions, the compiler can do some optimizations based on the assumption exceptions do not exit this method. A method marked with noexcept can have internal exceptions, but no exception may escape. If that happens, the program is forcefully terminated with std::terminate.

noexcept can also be used in code to check if an expression is exception safe or not. Use of noexcept falls outside the scope of this section.

Exception constraints checks only if the expression is evaluated to true. There is no way of requiring the expression to be noexcept(false). But it is possible to negate the exception constraint itself so it essentially is noexcept(false).

template<typename T>
void no_except(T t) noexcept
{}

Start with a method marked noexcept.

template<typename T>
concept bool ExceptionConstraint = requires(T t)
{
    {no_except(t)} noexcept;
};

This becomes an exception constraint based on the presence of the noexcept specifier. It will check if no_except(t) is marked with noexcept. Any method not marked with noexcept or noexcept(false) will fail this check.

void test_exception(ExceptionConstraint ec)
{}

Only types who will not throw exceptions with no_except are allowed to be called with test_exception.

To negate the exception constraint, one must use the longer requires syntax for concepts.

template<typename T>
requires !ExceptionConstraint<T> 
void negate_test_exception(T ec)
{}

Notice the exclamation mark, it will negate ExceptionConstraint and require the method to be the equivalent of noexcept(false).

Professional Software Developer, doing mostly C++. Connect with Kent on Twitter.