Есть две широко используемые реализации статического утверждения для версий C ++, которые не имеют встроенного static_assert
.
Первый используется в Boost и использует шаблон и специализацию этого шаблона :
template struct static_assert;
template <> struct static_assert {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
Здесь, когда условие для проверки ложно, компилятор не может найти общую версию шаблона и компиляция не удалась.
второй использует typedef
:
#define STATIC_ASSERT( x ) typedef char __STATIC_ASSERT__[( x )?1:-1]
Здесь, как только условие для проверки нарушено, компилятор пытается typedef
массив размера -1 и это незаконно, следовательно, ошибка времени компиляции.
Для меня последний вариант лучше, поскольку он гарантированно не испускает код, а также его можно использовать следующим образом (из здесь ):
template class BinaryFlag {
STATIC_ASSERT( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
public:
static const DWORD FlagValue = static_cast( 1 << Shift );
};
#define BINARY_FLAG( n ) CBinaryFlag::FlagValue
в то время как первый не может быть использован таким образом.
Есть ли какая-то причина предпочесть первую реализацию static assert второму?