在C++中,我需要定义一个宏.该宏将把参数作为代码的"块".
我们可以安全地使用几行代码作为宏函数的参数吗?
我问自己是否:
#define MY_MACRO( expr ) DOSOMETHING( (expr) ); DOANOTHERTHING( (expr) ); // etc...
int my_function() {
int o = RandomNumber();
MY_MACRO(
int k = AFunction();
k++;
AnotherFunction( k + o ); // here I need to keep the context of the call
);
}
Run Code Online (Sandbox Code Playgroud)
我们不能使用仿函数,因为我们需要访问调用的上下文.我们不能使用lambda(snif),因为我们使用的是一个不提供它的旧编译器(我们无法更改它).
16.3/9:
在构成类函数宏调用的预处理令牌序列中,换行被认为是正常的空白字符.
所以多行宏调用一般都没问题.当然,如果DOSOMETHING并且DOANOTHERTHING不介绍范围的大括号,那么您的特定示例将重新定义k.
编辑:
我们不能使用仿函数,因为我们需要访问调用的上下文.我们不能使用lambda(snif),因为我们使用旧的编译器
通常的方法是捕获函数中所需的变量,就像lambda一样.一个lambda可以做的唯一的事情是仿函数不能"捕获所有东西"而不必输入它,但是编写lambda的人可以看到他们使用的变量,所以这只是方便,如果他们可以输入全部必须.在你的例子中:
struct MyFunctor {
int o;
MyFunctor(int o) : o(o) {}
void operator()() const { // probably not void in practice
int k = AFunction();
k++;
AnotherFunction( k + o );
}
};
template<typename F>
void DoThings(const F &f) {
DOSOMETHING(f());
DOANOTHERTHING(f());
}
int my_function() {
int o = RandomNumber();
DoBothThings(MyFunctor(o));
}
Run Code Online (Sandbox Code Playgroud)
您还可以通过引用捕获变量(通常使用指针作为数据成员而不是引用,以便可以对仿函数进行复制分配).
如果通过"context",你的意思是例如宏参数和/或宏体可能包含一个break或goto,因此需要在调用者的词法范围内,那么你就不能使用仿函数或lambda.耻辱 ;-)
| 归档时间: |
|
| 查看次数: |
7159 次 |
| 最近记录: |