[英]How to do static_assert with macros?
I have tried to use this suggestion to do a static assert, but I do not get a compilation error if I use it within a method of a template. 我尝试使用此建议执行静态断言,但是如果在模板方法中使用它,则不会出现编译错误。
The example follows : 示例如下:
#include <iostream>
#define STATIC_ASSERT(expr, msg) \
{ \
char STATIC_ASSERTION__##msg[(expr)?1:-1]; \
(void)STATIC_ASSERTION__##msg[0]; \
}
template <typename T >
class A
{
public:
int foo(const int k )
{
// does not work
STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
};
int bar(const int k )
{
// works fine
//STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
int main()
{
A<int> a;
const int v = 2;
std::cout<<a.foo(v)<<std::endl;
std::cout<<bar(v)<<std::endl;
// works fine
//STATIC_ASSERT( v > 9, error_msg );
}
I compiled it with g++ 4.7.2, with a warning that VLAs are not supported by c++ ISO : 我用g ++ 4.7.2编译了它,并警告说c ++ ISO不支持VLA:
g++ -Wall -g -std=c++98 -Wextra -pedantic gvh.cpp
So, why the compilation doesn't fail when the STATIC_ASSERT is used within the template method? 那么,为什么在模板方法中使用STATIC_ASSERT时编译不会失败? Is there a way to make it fail?
有没有办法使它失败?
NOTE : I need a c++98 (maybe even c++03) solution, if possible only with macros. 注意 :我需要一个c ++ 98(甚至c ++ 03)解决方案,如果可能的话,只能使用宏。
Prior to C++11 I would normally do: 在C ++ 11之前,我通常会这样做:
typedef int static_assert_something[something ? 1 : -1];
You can also look at boost static assert . 您还可以查看boost静态assert 。 But it is too bloated for my liking.
但这太my肿了,我不喜欢。 It is easy to make things bigger, it is hard to make them any better.
使事情变大是容易的,使它们变更好是困难的。
Consider something like Boost.StaticAssert , although if that is unavailable to you you can try defining a template. 考虑一下Boost.StaticAssert之类的东西,尽管如果您不可用,可以尝试定义一个模板。
template<bool>
struct static_assertion;
template<>
struct static_assertion<true> {};
Though that has the drawback of not having a message associated to it. 尽管这样做的缺点是没有与之关联的消息。
After a bit of searching through StackOverflow, I stumbled upon this question which had a similar answer to mine and a bunch of alternatives for doing it without boost. 在对StackOverflow进行了一些搜索之后,我偶然发现了这个问题 , 该问题的答案与我的相似,并且提供了许多无需提高就可以实现的替代方法。
This is basically Maxim's answer with a little more convenient interface. 这基本上是Maxim的回答,界面更加方便。 I have taken it from here .
我从这里拿走的。 Nice thing about it is that the use of templates prevents the user from passing a non-compile-time-constant value as the condition.
关于它的好处是,模板的使用可防止用户传递非编译时常数值作为条件。
template<bool Is_Condition_Met>
struct Static_assert_cpp98
{
static void apply() {static const char junk[ Is_Condition_Met ? 1 : -1 ];}
};
template<>
struct Static_assert_cpp98<true>
{
static void apply() {}
};
#define STATIC_ASSERT_CPP98(condition) Static_assert_cpp98<condition>::apply()
If you add call to the method in question (a.foo();), the static assert will fail (just then the method will be compiled). 如果将调用添加到有问题的方法(a.foo();),则静态断言将失败(仅将编译该方法)。 You do know that you should not static assert on run time values like "k" I presume.
您知道您不应该对我假设的运行时值(例如“ k”)进行静态断言。
int foo(const int k)
{
STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
Static assertions only work with compile-time constant expressions. 静态断言仅适用于编译时常量表达式。
k
is not a compile-time constant expression. k
不是编译时常量表达式。
Non-type template parameters are compile-time constant expressions during template instantiation, so you could adapt your code thus: 非类型模板参数是模板实例化期间的编译时常量表达式,因此您可以这样修改代码:
template <int K>
int foo()
{
STATIC_ASSERT( K > 9, error_msg );
return K+5;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.