[英]Static Assert to check compile-time-constant is NOT passed to macro
前言:
switch(nValue)
{
case X:
...
case Y:
...
default:
ASSERT_FOR_DEFAULT(nValue);
}
ASSERT_FOR_DEFAULT
是一个宏,它将显示一个(自定义)断言对话框,以报告点击“default-case”。 是的,这个宏用于运行时断言,而不是编译时断言。 但是,我只需要那个,任何常量值(编译时)都不能传递给这个宏。
问题:
以下应该在编译时失败:
ASSERT_FOR_DEFAULT(5);
是的,程序员可以在任何地方使用它,而不仅仅是在switch-case
default
情况switch-case
。 他还可以使用switch
未使用的任何表达式。 但这不是问题。 只需要将非常量传递给这个宏。
这个宏没有什么重要的东西,假设它是ASSERT
/ assert
。
我尝试过模板(使用其他 SFINAE/静态断言!),数组(如strcpy_s
),自己的结构具有YES
, NO
类型等等。 但是找不到解决办法!
我正在使用 VC2008。 我知道static_assert
、 decltype
等,但不能使用 C++0x。
编辑(解决方案):
#define STATIC_ASSERT(expr) {int array[!!(expr)]; expr;}
template <class T>
bool noConstAllowed(T&);
int noConstAllowed(...);
#define ASSERT_FOR_DEFAULT_VALUE(val) \
{ \
STATIC_ASSERT(sizeof(noConstAllowed(val))==sizeof(bool)); \
}
int main()
{
int test=10;
ASSERT_FOR_DEFAULT_VALUE(test);
ASSERT_FOR_DEFAULT_VALUE(2);
ASSERT_FOR_DEFAULT_VALUE(test+2); //FAILS, but okay for me!
}
感谢 Arne Mertz 提出这个可爱的建议。 我从中得出了解决方案。 noConstAllowed
为所有T&
类型重载,如果传递常量值,将调用另一个重载。 两者都有不同的返回类型,因此检查大小。 模板版本返回一个bool
,它满足传递的任何变量的断言,并且对于任何常量或表达式都失败(因为返回类型将是int
)。
您可以重新定义宏,以便它采用参数的地址 - 这对于文字应该失败。 但是,这不会阻止您传递常量变量,例如
const static int FIVE = 5;
ASSERT_FOR_DEFAULT(FIVE); // still works.
要禁止将各种常量传递给宏,请调用一个通过非常量引用获取参数的函数:
template <class T> void noConstAllowed(T&){};
#define ASSERT_FOR_DEFAULT_VALUE(val) \
{ \
(void*)&(val); /* no literals*/ \
noConstAllowed(val); /* no constants at all */ \
switchHitDefaultDialog(val, __FILE__, __LINE__); \
}
我想你使用类似FILE或其他位置宏的东西,或者你会把它变成一个函数。 其中,您只需要使用两行之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.