Что-то вроде
void assert_impl() { assert(false); } // Replace body with own implementation
#ifdef NDEBUG // Replace with own conditional
#define my_assert(condition) ((void)0)
#else
#define my_assert(condition) ((condition) ? (void()) : (assert_impl(), void()))
#endif
template<int Size>
struct Array {
int m_vals[Size];
constexpr const int& getElement( int idx ) const
{
return my_assert(idx < Size), m_vals[idx];
}
};
Это даст ошибку времени компиляции при ошибке подтверждения при использовании в контексте , требующем константного выражения (потому что это вызовет не-constexpr
function).
Иначе во время выполнения произойдет сбой при вызове assert
(или вашего аналога).
Это лучшее, что вы можете сделать, насколько я знаю. Невозможно использовать значение idx
для принудительной проверки во время компиляции вне контекста , требующего константных выражений.
Синтаксис оператора запятой не очень приятный, но C + +11 constexpr
функции очень ограничены.
Конечно, как вы уже отметили, неопределенное поведение будет диагностироваться в любом случае, если функция используется в контексте, требующем постоянного выражения.
Если вы знаете, что assert
(или ваш аналог) не распространяется на что-либо, что запрещено в константном выражении, если условие оценивается как true
, но делает это, если оно оценивается как false
, тогда вы можете использовать его непосредственно вместо my_assert
и пропустите косвенное указание, которое я строю в своем коде.