cons 变量的静态断言?
静态断言对于在编译时检查事物非常方便。一个简单的静态断言习惯用法如下所示:
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
这对于 and 之类的东西很有用
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;
这样做的问题是,使用 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 asserts are very convenient for checking things in compile time. A simple static assert idiom looks like this:
template<bool> struct StaticAssert;
template<> struct StaticAssert<true> {};
#define STATIC_ASSERT(condition) do { StaticAssert<(condition)>(); } while(0)
This is good for stuff like
STATIC_ASSERT(sizeof(float) == 4)
and:
#define THIS_LIMIT (1000)
...
STATIC_ASSERT(THIS_LIMIT > OTHER_LIMIT);
But using #define
is not the "C++" way of defining constants. C++ would have you use an anonymous namespace:
namespace {
const int THIS_LIMIT = 1000;
}
or even:
static const int THIS_LIMIT = 1000;
The trouble with this is that with a const int
you can't use STATIC_ASSERT()
and you must resort to a run-time check which is silly.
Is there a way to properly solve this in current C++?
I think I've read C++0x has some facility to do this...
EDIT
Ok so this
static const int THIS_LIMIT = 1000;
...
STATIC_ASSERT(THIS_LIMIT > 0);
compiles fine
But this:
static const float THIS_LIMIT = 1000.0f;
...
STATIC_ASSERT(THIS_LIMIT > 0.0f);
does not.
(in Visual Studio 2008)
How come?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
为什么,你仍然可以使用 const int 进行静态断言:
另外,使用 boost !
...您会收到很多更好的错误消息...
Why, you can still static assert with const int:
Also, use boost!
... you'll get a lot nicer error messages...
static_assert
是 C++0x 中的编译器功能,因此只要您拥有相对最新的编译器,就可以使用它。请注意执行#define static_assert(x) ...
,因为它是 C++0x 中的真正关键字,因此您将永久隐藏编译器功能。另外,C++0xstatic_assert
采用两个参数(例如static_assert(sizeof(int) == 4, "Expecting int to be 4 bytes")
),因此您如果您使用#define,可能会导致您将来尝试切换时出现问题。static_assert
is a compiler feature in C++0x so as long as you've got a relatively up-to-date compiler you can use that. Watch out for doing#define static_assert(x) ...
, because it's a real keyword in C++0x so you'd be permanently hiding the compiler feature. Also, C++0xstatic_assert
takes two parameters (eg.static_assert(sizeof(int) == 4, "Expecting int to be 4 bytes")
), so you could cause yourself problems trying to switch in future if you use that #define.看来您真的问为什么会出现以下情况(我可以在 GCC 4.3.4 和 Visual C++ 2008 Express 中确认这一点):
使用浮点有很多限制静态值。例如,请注意,您不能将它们作为模板参数传递。那是因为:
(即只允许整型和枚举类型;不允许浮点类型。)
至于此规则的原因,我不完全确定,但以下理由可能是我们与它有关:
It seems that you're really asking why the following is the case (and I can confirm that in both GCC 4.3.4 and Visual C++ 2008 Express):
There are number of restrictions on using floating-point values statically. Note, for example, that you cannot pass them as template arguments. That is because:
(i.e. only integral and enumeration types are allowed; no floating-point types.)
As for the reason for this rule, I'm not entirely sure, but the following sort of rationale may well have something to do with it:
也许您将 C++ 的行为与 C 混淆了,其中
const int
并不代表真正的编译时常量。或者你的 C++ 编译器可能坏了。如果确实是后者,请改用enum
。Perhaps you're confusing C++'s behavior with C, where
const int
does not represent a true compile-time constant. Or perhaps your C++ compiler is broken. If it's truly the latter, useenum
instead.这:
用 VC 和 Comeau 编译得很好。
This:
compiles fine with VC and Comeau.
枚举{THIS_LIMIT = 1000};
enum{THIS_LIMIT = 1000};