C ++:忽略声明
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++:忽略声明相关的知识,希望对你有一定的参考价值。
我正在使用C ++预处理器宏来选择性地忽略一些代码块以用于测试目的,例如
#ifdef __SAFE
#define note
#define ensure(X) if(X) {} else
#else
#define note while(false)
#define ensure(X) while(false)
#endif
直观地说,note
执行一些代码(通常设置一些保护变量),如果条件被违反,ensure
会执行下一个代码块。有了这些宏,我可以写:
note { var = true }
ensure(var == true) { throw new std::exception; }
并且代码将编译是否定义了__SAFE
(并且编译器很可能会摆脱dummied out代码)。这很好,因为它的行为基本上是C ++语言的扩展。
当__SAFE
未定义时,我也想在类中跳过一些数据成员声明。上面的技巧不再起作用,因为在类声明中不允许流控制。我想声明一些宏guard
为哪个类:
class A {
guard int x;
}
仅在定义int x
时包含成员__SAFE
。
可能的解决方案:
- 一些预编译器技巧能够用
guard
替换//
,从而获得所需的结果;但它们只适用于某些编译器(尤其不适用于g++
)。此外,似乎在预处理之前删除了注释,因此它可能无论如何都不会起作用。 - 用
#ifdef ... #endif
块围绕声明。它有效,但有点冗长。 - 如果定义了
guard(X)
,则将X
定义为__SAFE
,否则定义为空格。这也有效,但摆脱括号会很好,只需将参数作为“一切直到下一个分号”。
我知道C ++预处理器不是很强大。我想知道是否有一个美学上令人愉悦的解决方案;否则我会简单地使用后一种选择。
答案
从C ++ 11开始,您可以使用模板别名,例如:
struct A {
guarded<int> x;
};
其中guarded
定义为:
#ifdef YOUR_SAFE_MACRO
template<typename T>
using guarded_impl = T;
#define guarded guarded_impl
#else
template<typename T>
struct guarded_impl {};
#define guarded static guarded_impl
#endif
如果在YOUR_SAFE_MACRO
关闭时变量是ODR使用,那么这也会产生链接器错误(如果打开,则虚拟静态变量仍然存在,但如果未使用则应在链接时进行优化)。
您也可以在<C ++ 11中执行此操作,但它会稍微冗长一些。
也就是说,我想注意,确保和守卫是太常见的名称,不能用作宏,仍然希望不会发生名称冲突,所以我强烈建议反对这样的事情(你已被警告:))
此外,阅读你的代码的人会因为将qazxsw poi隐藏在一个看起来像模板的宏中而感到困惑......在我看来,一个好的ol qazxsw poi将是一个更好的解决方案。
以上是关于C ++:忽略声明的主要内容,如果未能解决你的问题,请参考以下文章