Static утверждает, очень удобны для проверки вещей во время компиляции. Простые помехи утверждают, что идиома похожа на это:
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
Это хорошо для материала как
STATIC_ASSERT(sizeof(float) == 4)
и:
#define THIS_LIMIT (1000)
...
STATIC_ASSERT(THIS_LIMIT > OTHER_LIMIT);
Но использование #define
не "C++" способ определить константы. C++ сделал бы, чтобы Вы использовали анонимное пространство имен:
namespace {
const int THIS_LIMIT = 1000;
}
или даже:
static const int THIS_LIMIT = 1000;
Проблема с этим - это с a const int
Вы не можете использовать STATIC_ASSERT()
и необходимо обратиться к проверке на этапе выполнения, которая глупа.
Существует ли способ правильно решить это в текущем C++?
Я думаю, что читал, C++ 0x имеет некоторое средство, чтобы сделать это...
Править
Хорошо так это
static const int THIS_LIMIT = 1000;
...
STATIC_ASSERT(THIS_LIMIT > 0);
прекрасные компиляции
Но это:
static const float THIS_LIMIT = 1000.0f;
...
STATIC_ASSERT(THIS_LIMIT > 0.0f);
не делает.
(в Visual Studio 2008)
Каким образом?
Почему, вы все еще можете использовать static assert с const int:
#define static_assert(e) extern char (*ct_assert(void)) [sizeof(char[1 - 2*!(e)])]
static_assert( THIS_LIMIT > OTHER_LIMIT )
Также, используйте boost!
BOOST_STATIC_ASSERT( THIS_LIMIT > OTHER_LIMIT )
... вы получите много более приятных сообщений об ошибках...
static_assert
- это функция компилятора в C ++ 0x, поэтому, если у вас есть относительно современный компилятор, вы можете его использовать. Не упустите возможность выполнить #define static_assert (x) ...
, потому что это настоящее ключевое слово в C ++ 0x, поэтому вы навсегда скроете функцию компилятора. Кроме того, C ++ 0x static_assert
принимает два параметра (например, static_assert (sizeof (int) == 4, «Ожидается, что int будет 4 байта»)
), поэтому вы можете вызвать у себя проблемы, пытающиеся переключиться в будущем, если вы используете этот #define.
Это:
namespace {
const int THIS_LIMIT = 1000;
}
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
int main()
{
STATIC_ASSERT(THIS_LIMIT > 5);
return (0);
}
отлично компилируется с VC и Comeau.
Возможно, вы путаете поведение C++ с C, где const int
не представляет собой истинную константу времени компиляции. Или, возможно, ваш компилятор C++ сломан. Если это действительно последнее, используйте enum
вместо этого.