GCC is right. However, there is a relatively simple way:
#include "assert.h" inline void assert_helper( bool test ) { assert(test); } inline constexpr bool constexpr_assert( bool test ) { return test?true:(assert_helper(test),false); } template<typename T> constexpr inline T getClamped(const T& mValue, const T& mMin, const T& mMax) { return constexpr_assert(mMin < mMax), (mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue)); }
where we use the comma operator twice.
The first time, because we want to have an assert , which, when true , can be called from the constexpr function. The second, so we can connect two functions into one constexpr function.
As a side benefit, if the constexpr_assert expression cannot be verified as true at compile time, then the getClamped function getClamped not constexpr .
assert_helper exists because the contents of assert is an implementation defined when NDEBUG is true, so we cannot insert it into an expression (it can be an operator, not an expression). This also ensures that the failure of constexpr_assert cannot be constexpr , even if assert is constexpr (say when NDEBUG is false).
The disadvantage of all this is that your statement does not work on the line where the problem occurs, but on 2 calls deeper.
source share