参数有几行的宏​​函数? [英] Macro function with several lines for the parameter?

查看:12
本文介绍了参数有几行的宏​​函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In C++, I need to defined a macro. That macro would take as parameter a "block" of code.

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

我在问自己是否:

  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
    ); 
}

我们不能使用仿函数,因为我们需要访问调用的上下文.我们不能使用 lambda (snif),因为我们使用的是不提供它的旧编译器(而且我们无法更改它).

We can't use functors because we need to have access to the context of the call. We can't use lambda (snif) because we use an old compiler that don't provide it (and we can't change it).

推荐答案

16.3/9:

在预处理序列内构成对 a 的调用的标记类似函数的宏,换行符是被认为是正常的空白字符.

Within the sequence of preprocessing tokens making up an invocation of a function-like macro, new-line is considered a normal white-space character.

所以一般来说多行宏调用是可以的.当然,如果 DOSOMETHINGDOANOTHERTHING 没有为范围引入大括号,那么您的特定示例将重新定义 k.

So the multi-line macro invocation in general is fine. Of course if DOSOMETHING and DOANOTHERTHING don't introduce braces for scope, then your particular example will redefine k.

我们不能使用函子,因为我们需要访问上下文称呼.我们不能使用 lambda (snif),因为我们使用的是旧编译器

We can't use functors because we need to have access to the context of the call. We can't use lambda (snif) because we use an old compiler

通常的方法是在仿函数中捕获您需要的任何变量,就像 lambda 一样.lambda 唯一能做而仿函数不能做的是捕获所有内容"而不必输入它,但是编写 lambda 的人可以看到他们使用的变量,所以这只是方便,如果他们可以将它们全部输入必须.在您的示例中:

The usual way is to capture whichever variables you need in the functor, just like a lambda does. The only thing a lambda can do that a functor can't is "capture everything" without having to type it out, but whoever writes the lambda can see what variables they use, so that's just convenience, they could type them all out if they had to. In your example:

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));
}

您还可以通过引用捕获变量(通常使用指针作为数据成员而不是引用,以便可以对仿函数进行复制分配).

You can also capture variables by reference (usually using a pointer as the data member rather than a reference, so that the functor can be copy-assigned).

如果使用上下文",您的意思是例如宏参数和/或宏主体可能包含 breakgoto,因此需要在里面调用者的词法范围,那么你不能使用仿函数或 lambda.惭愧 ;-)

If by "context", you mean for example that the macro argument and/or the macro body might contain a break or goto, and hence needs to be inside the lexical scope of the caller then you can't use a functor or a lambda. For shame ;-)

这篇关于参数有几行的宏​​函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆