Пожалуйста, помогите мне понять этот синтаксис (реализация статического утверждения в C ++) - PullRequest
6 голосов
/ 23 июня 2010

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

template <bool>
struct static_assert;

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

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

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

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

STATIC_ASSERT(true);

конвертируется в

static_assert<true>();

Что теперь?

Ответы [ 4 ]

13 голосов
/ 23 июня 2010
STATIC_ASSERT(true);

действительно означает

static_assert<true>();

, что ничего не значит.static_assert<true> это просто пустая структура без каких-либо членов.static_assert<true>() создает объект этой структуры и нигде не сохраняет его.

Это просто компилируется и ничего не делает.

С другой стороны

STATIC_ASSERT(false);

означает

static_assert<false>();

, что приводит к ошибке компиляции.static_assert не имеет специализации для false.Таким образом, общая форма используется.Но общая форма выглядит следующим образом:

template <bool>
struct static_assert;

, которая является просто декларацией структуры, а не ее определением.Таким образом, static_assert<false>() вызывает ошибку компиляции, поскольку он пытается создать объект структуры, которая не определена.

9 голосов
/ 23 июня 2010

static_assert<true>(); делает это

template <>
struct static_assert<true> {}

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

4 голосов
/ 23 июня 2010

в выражении

static_assert<true>();

, поскольку static_assert<true> является типом, он вызывает конструктор static_assert<true>. Поскольку static_assert<true> специализируется на пустой структуре, ничего не будет затронуто.


Однако в

static_assert<false>();

, поскольку для static_assert<false> нет специализации, общее определение

template <bool>
struct static_assert;

будет использоваться. Но здесь тип static_assert<B> является неполным . Таким образом, вызов конструктора static_assert<B> приведет к ошибке компиляции.


Следовательно, это называется «статическим утверждением», поскольку оператор прервет компиляцию, если выражение оценивается как false, аналогично нормальной assert() функции , которая убьет программу во время выполнения.

2 голосов
/ 23 июня 2010

Ну, наверное, речь идет о специализации шаблонов.STATIC_ASSERT (true) успешно скомпилируется, потому что есть определение (не просто объявление) «static_assert ».

STATIC_ASSERT (false) будет отклонено компилятором, поскольку существует только объявлениедля "static_assert " и без определения.

Обновление: для Visual Studio STATIC_ASSERT (true) в порядке, но STATIC_ASSERT (false) вызывает ошибку: "error C2514:" static_assert <__ formal> 'класс не имеет конструкторов [с __formal = false] "

...