具有多行参数的宏功能?

Kla*_*aim 13 c++ macros

在C++中,我需要定义一个宏.该宏将把参数作为代码的"块".

我们可以安全地使用几行代码作为宏函数的参数吗?

我问自己是否:

  1. 以下代码是否有效,由标准定义为有效,如"跨平台"?
  2. 是否有更好的方法来做同样的事情(我不能在那里使用模板函数,因为我需要上下文).

#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),因为我们使用的是一个不提供它的旧编译器(我们无法更改它).

Ste*_*sop 9

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",你的意思是例如宏参数和/或宏体可能包含一个breakgoto,因此需要在调用者的词法范围内,那么你就不能使用仿函数或lambda.耻辱 ;-)