前言:
switch(nValue)
{
case X:
...
case Y:
...
default:
ASSERT_FOR_DEFAULT(nValue);
}
ASSERT_FOR_DEFAULT
是一个宏,它将显示一个(自定义)断言对话框,以报告命中“默认情况”。是的,这个宏用于运行时断言,而不是编译时断言。但是,我只需要这样,任何常量值(编译时)都不能传递给这个宏。
问题:
以下应该在编译时失败:
ASSERT_FOR_DEFAULT(5);
是的,程序员可以在任何地方使用它,而不仅仅是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&
类型重载,如果传递了常量值,将调用另一个重载。两者都有不同的返回类型,因此检查大小。模板版本返回 a bool
,它满足任何传递的变量的断言,并且对于任何常量或表达式都失败(因为返回类型将为int
)。