Помогите мне понять, этот синтаксис (реализующий статичный утверждают в C++),

Этот синтаксис использовался в качестве части ответа на этот вопрос:

template 
struct static_assert;

template <>
struct static_assert {}; // only true is defined

#define STATIC_ASSERT(x) static_assert<(x)>()

Я не понимаю тот синтаксис.Как это работает?

Предположим, что я делаю

STATIC_ASSERT(true);

это преобразовывается в

static_assert();

Теперь, что?

6
задан Community 23 May 2017 в 11:46
поделиться

4 ответа

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() вызывает ошибку компиляции, так как пытается сделать объект структуры, которая не определена.

13
ответ дан 8 December 2019 в 03:38
поделиться

static_assert(); делает то

template <>
struct static_assert<true> {}

templated struct специализация временное создание объекта - вызов конструктора, а затем деструктора, которые оба будут, надеюсь, устранены оптимизатором, поскольку они ничего не делают. Поскольку есть только специализация для true и нет общей версии шаблонной структуры, все конструкции, которые оцениваются как static_assert(); просто не будут компилироваться.

9
ответ дан 8 December 2019 в 03:38
поделиться

В выражении

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 , который убьет программу во время выполнения.

4
ответ дан 8 December 2019 в 03:38
поделиться

Ну, я полагаю, что дело в специализации шаблонов. 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 ]"

.
2
ответ дан 8 December 2019 в 03:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: