Macro function with several lines for the parameter?(参数有几行的宏函数?)
问题描述
在 C++ 中,我需要定义一个宏.该宏会将代码块"作为参数.
In C++, I need to defined a macro. That macro would take as parameter a "block" of code.
我们可以安全地使用几行代码作为宏函数的参数吗?
我在问自己是否:
- 以下代码是否有效,被标准定义为有效,如跨平台"中的?
- 有没有更好的方法来做同样的事情(我不能在那里使用模板函数,因为我需要上下文).
<小时>
#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.
所以一般来说多行宏调用是可以的.当然,如果 DOSOMETHING 和 DOANOTHERTHING 没有为范围引入大括号,那么您的特定示例将重新定义 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).
如果使用上下文",您的意思是例如宏参数和/或宏主体可能包含 break 或 goto,因此需要在里面调用者的词法范围,那么你不能使用仿函数或 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 ;-)
这篇关于参数有几行的宏函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:参数有几行的宏函数?
基础教程推荐
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- CString 到 char* 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 初始化列表*参数*评估顺序 2021-01-01
