утверждение времени компиляции в c ++

Я читаю утверждение времени компиляции, после поиска в Интернете я получил код, который я не понял.

template <bool> struct CompileAssert {};
#define COMPILE_ASSERT(expr, msg) \
    typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]

Использовал этот COMPILE_ASSERT, как показано ниже.

COMPILE_ASSERT(!sizeof(T*), PassRefPtr_should_never_be_assigned_to)

Но у меня не было идеи. Может кто-нибудь помочь мне разобраться в приведенном выше фрагменте кода. Второй запутался в этом фрагменте кода

typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]

#Define заменит COMPILE_ASSERT (expr, msg) указанным выше выражением. Но как msg [bool (expr)? 1: -1] альтернативный тип для CompileAssert ‹(bool (expr))>.

Пожалуйста, объясните подробно и просто. У меня много много вопросов.

Например, почему сообщение (PassRefPtr_should_ Never_be_assigned_to) работает без использования "" для char *


person dead programmer    schedule 08.05.2013    source источник


Ответы (2)


Если вы передадите макросу выражение, которое имеет значение false, макрос выдаст typedef, как показано ниже:

typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[false ? 1 : -1];

который

typedef CompileAssert<false> PassRefPtr_should_never_be_assigned_to[-1];

Итак, поскольку отрицательная длина массива недопустима, компилятор выдаст ошибку для typedef, содержащую «msg» в качестве имени массива.

person Arne Mertz    schedule 08.05.2013
comment
Так что это не имеет значения, погодные условия. ComplieAssert ‹true› или compileAssert ‹false›, это просто проверяет действительность arrayyname, имеет ли правильное имя или нет ... поэтому я думаю, что будет то же самое, если я использую typedef int msg [bool (expr) ? 1: -1] - person dead programmer; 08.05.2013

typedef будет называть легальный или недопустимый фрагмент кода в зависимости от значения expr.

Скажем, bool(expr) это true. В этом случае typedef эквивалентен

typedef CompileAssert<true> msg[1];

Это 1-элементный массив из CompileAssert<true> структур с именем msg. Поскольку CompileAssert<bool> является определенной структурой, все в порядке.

Однако, если bool(expr) равно false, typedef будет эквивалентен следующему:

typedef CompileAssert<false> msg[-1];

Это, конечно, незаконно (вы не можете создать массив размером -1), поэтому компилятор сообщит об ошибке, что msg неправильно сформирован. И поскольку msg является параметром макроса, на самом деле это будет текст, указанный в COMPILE_ASSERT, поэтому сообщение об ошибке для вашего примера может выглядеть примерно так:

Cannot create array PassRefPtr_should_never_be_assigned_to of size -1.

Также обратите внимание, что C ++ 11 имеет встроенный static_assert.

person Angew is no longer proud of SO    schedule 08.05.2013
comment
typedef CompileAssert<false> msg[-1]; вы имеете в виду (изменено с истины на ложь) - person Mats Petersson; 08.05.2013
comment
Так что это не имеет значения, погодные условия. ComplieAssert ‹true› или compileAssert ‹false›, это просто проверяет действительность arrayyname, имеет ли правильное имя или нет ... поэтому я думаю, что будет то же самое, если я использую typedef int msg [bool (expr) ? 1: -1] - - person dead programmer; 08.05.2013
comment
@YSBhai Да, с int тоже будет работать. Обычно шаблон bool используется, когда вы даете правильное определение только для случая true. Кажется, что этот макрос смешивает эти подходы, не понимая их. - person Angew is no longer proud of SO; 08.05.2013