静态断言非常便于在编译时检查事物.一个简单的静态断言习惯用法如下:
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
Run Code Online (Sandbox Code Playgroud)
这对于像这样的东西很有用
STATIC_ASSERT(sizeof(float) == 4)
Run Code Online (Sandbox Code Playgroud)
和:
#define THIS_LIMIT (1000)
...
STATIC_ASSERT(THIS_LIMIT > OTHER_LIMIT);
Run Code Online (Sandbox Code Playgroud)
但是使用#define不是定义常量的"C++"方式.C++会让你使用匿名命名空间:
namespace {
const int THIS_LIMIT = 1000;
}
Run Code Online (Sandbox Code Playgroud)
甚至:
static const int THIS_LIMIT = 1000;
Run Code Online (Sandbox Code Playgroud)
这样做的问题在于,const int你不能使用STATIC_ASSERT(),你必须采用愚蠢的运行时检查.
有没有办法在当前的C++中正确解决这个问题?
我想我已经读过C++ 0x有一些工具可以做到这一点......
编辑
好的,这个
static const int THIS_LIMIT = 1000;
...
STATIC_ASSERT(THIS_LIMIT > 0);
Run Code Online (Sandbox Code Playgroud)
编译好
但是这个:
static const float THIS_LIMIT = 1000.0f;
...
STATIC_ASSERT(THIS_LIMIT > 0.0f);
Run Code Online (Sandbox Code Playgroud)
才不是.
(在Visual Studio 2008中)
怎么会?
Kor*_*icz 11
为什么,你仍然可以使用const int静态断言:
#define static_assert(e) extern char (*ct_assert(void)) [sizeof(char[1 - 2*!(e)])]
static_assert( THIS_LIMIT > OTHER_LIMIT )
Run Code Online (Sandbox Code Playgroud)
另外,使用提升!
BOOST_STATIC_ASSERT( THIS_LIMIT > OTHER_LIMIT )
Run Code Online (Sandbox Code Playgroud)
......你会得到很多更好的错误消息...
static_assert是C++ 0x中的编译器功能,所以只要你有一个相对最新的编译器就可以使用它.注意这样做#define static_assert(x) ...,因为它是C++ 0x中的一个真正的关键字,所以你永远隐藏了编译器功能.此外,C++ 0x static_assert有两个参数(例如.static_assert(sizeof(int) == 4, "Expecting int to be 4 bytes")),因此如果你使用#define,你可能会在将来尝试切换时遇到问题.