Этот синтаксис использовался в качестве части ответа на этот вопрос:
template
struct static_assert;
template <>
struct static_assert {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
Я не понимаю тот синтаксис.Как это работает?
Предположим, что я делаю
STATIC_ASSERT(true);
это преобразовывается в
static_assert();
Теперь, что?
STATIC_ASSERT(true);
действительно означает
static_assert<true>();
что ничего не оценивает. static_assert
- это просто пустая структура без каких-либо членов. static_assert
создает объект этой структуры и нигде его не хранит.
Это просто компилируется и ничего не делает.
С другой стороны
STATIC_ASSERT(false);
средство
static_assert<false>();
которое приводит к ошибке компиляции. static_assert
не имеет специализации для false
. Поэтому используется общая форма. Но общая форма приведена следующим образом:
template <bool>
struct static_assert;
что является лишь объявлением структуры, а не ее определением. Поэтому static_assert
вызывает ошибку компиляции, так как пытается сделать объект структуры, которая не определена.
static_assert
делает то
template <>
struct static_assert<true> {}
templated struct специализация временное создание объекта - вызов конструктора, а затем деструктора, которые оба будут, надеюсь, устранены оптимизатором, поскольку они ничего не делают. Поскольку есть только специализация для true
и нет общей версии шаблонной структуры, все конструкции, которые оцениваются как static_assert
просто не будут компилироваться.
В выражении
static_assert<true>();
, поскольку static_assert
является типом, оно вызовет конструктор static_assert
. Поскольку static_assert
специализирован для пустой структуры, ничего не изменится.
Однако в
static_assert<false>();
, поскольку нет специализации для static_assert
, будет использоваться общее определение
template <bool>
struct static_assert;
. Но здесь тип static_assert
является неполным . Поэтому вызов конструктора static_assert
приведет к ошибке компиляции.
Таким образом, это называется «статическим утверждением», поскольку оператор прервет компиляцию, если выражение оценивается как false
, аналогично normal assert ()
function , который убьет программу во время выполнения.
Ну, я полагаю, что дело в специализации шаблонов. STATIC_ASSERT(true) успешно скомпилируется, потому что есть определение (а не просто объявление) "static_assert< true >".
STATIC_ASSERT(false) будет отвергнут компилятором, потому что есть только объявление для "static_assert< false >" и нет определения.
Обновление: для visual studio STATIC_ASSERT(true) работает нормально, но STATIC_ASSERT(false) вызывает ошибку: "error C2514: 'static_assert<__formal>' : class has no constructors [ with __formal = false ]"
.