Для тех, кто хочет что-то действительно простое и переносимое, но не имеет доступа к функциям C ++ 11, я написал только это.
Используйте STATIC_ASSERT
обычно (вы можете написать его дважды в одной и той же функции, если хотите) и использовать GLOBAL_STATIC_ASSERT
вне функций с уникальной фразой в качестве первого параметра.
#if defined(static_assert)
# define STATIC_ASSERT static_assert
# define GLOBAL_STATIC_ASSERT(a, b, c) static_assert(b, c)
#else
# define STATIC_ASSERT(pred, explanation); {char assert[1/(pred)];(void)assert;}
# define GLOBAL_STATIC_ASSERT(unique, pred, explanation); namespace ASSERTATION {char unique[1/(pred)];}
#endif
GLOBAL_STATIC_ASSERT(first, 1, "Hi");
GLOBAL_STATIC_ASSERT(second, 1, "Hi");
int main(int c, char** v) {
(void)c; (void)v;
STATIC_ASSERT(1 > 0, "yo");
STATIC_ASSERT(1 > 0, "yo");
// STATIC_ASSERT(1 > 2, "yo"); //would compile until you uncomment this one
return 0;
}
Пояснение:
Сначала он проверяет, есть ли у вас реальное утверждение, которое вы определенно хотели бы использовать, если оно доступно.
Если вы этого не сделаете, он получит ваш pred
лед и разделит его сам. Это делает две вещи.
Если оно равно нулю, то есть утверждение не удалось, это приведет к ошибке деления на ноль (арифметика принудительная, потому что она пытается объявить массив).
Если он не равен нулю, он нормализует размер массива до 1
. Таким образом, если утверждение прошло, вы бы не захотели, чтобы оно все равно не сработало, потому что ваш предикат оценивается как -1
(недопустимый) или 232442
(огромная трата пространства, IDK, если его оптимизировать).
Для STATIC_ASSERT
он заключен в фигурные скобки, что делает его блоком, в котором находится переменная assert
, что означает, что вы можете записать его много раз.
Он также приводит к void
, который является известным способом избавления от unused variable
предупреждений.
Для GLOBAL_STATIC_ASSERT
вместо того, чтобы находиться в блоке кода, он генерирует пространство имен. Пространства имен разрешены вне функций. Идентификатор unique
необходим для остановки любых противоречивых определений, если вы используете это более одного раза.
работал у меня на GCC и VS'12 C ++