Eric Niebler covers this issue well in Assert and Constexpr in C++11, he points out that using assert in a constexpr function is not allowed in C++11 but it is allowed in C++14(As part of the Relaxing constraints on constexpr functions proposal) and provides the following snippet:
constexpr bool in_range(int val, int min, int max)
{
assert(min <= max); // OOPS, not constexpr
return min <= val && val <= max;
}
If we have to support C++11 then there are some alternatives. The obvious one is the using throw but this as he points out this turns what should be a unrecoverable error into a recoverable one since you can catch the exception.
He suggest some alternatives:
Using throw with the noexcept specifier:
constexpr bool in_range(int val, int min, int max) noexcept
{
return (min <= max)
? min <= val && val <= max
: throw std::logic_error("Assertion failed!");
}
if an exception leaves the function std::terminate will be called.
Call std::quick_exit from the constructor of an exception type:
struct assert_failure
{
explicit assert_failure(const char *sz)
{
std::fprintf(stderr, "Assertion failure: %s\n", sz);
std::quick_exit(EXIT_FAILURE);
}
};
constexpr bool in_range(int val, int min, int max)
{
return (min <= max)
? min <= val && val <= max
: throw assert_failure("min > max!");
}
Pass a lambda expression that asserts to the constructor of an exception type:
constexpr bool in_range(int val, int min, int max)
{
return (min <= max)
? min <= val && val <= max
: throw assert_failure(
[]{assert(!"input not in range");}
);
}