Существует две широко используемые реализации статического утверждения для версий C ++, которые не имеют встроенной static_assert
.
Первый используется в Boost и использует шаблон и специализацию этого шаблона :
template <bool> struct static_assert;
template <> struct static_assert<true> {}; // 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<int Shift> class BinaryFlag {
STATIC_ASSERT( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
public:
static const DWORD FlagValue = static_cast<DWORD>( 1 << Shift );
};
#define BINARY_FLAG( n ) CBinaryFlag<n>::FlagValue
пока первое не может быть использовано таким образом.
Есть ли какая-либо причина предпочитать первую реализацию static assert второй?