具有多行参数的宏功能?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有多行参数的宏功能?相关的知识,希望对你有一定的参考价值。
在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
);
}
我们不能使用仿函数,因为我们需要访问调用的上下文。我们不能使用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));
}
您还可以通过引用捕获变量(通常使用指针作为数据成员而不是引用,以便可以对仿函数进行复制分配)。
如果通过“context”,你的意思是例如宏参数和/或宏体可能包含break
或goto
,因此需要在调用者的词法范围内,然后你不能使用functor或lambda 。耻辱 ;-)
使其工作的方式(至少对于gcc版本4.8.1(Ubuntu / Linaro 4.8.1-10ubuntu9)),是使用括号{}包含宏的实际值。
一个有用的例子:
#ifdef DEBUG
#define MYDEBUG(X) (X)
#else
#define MYDEBUG(X)
#endif
MYDEBUG({
if (shit_happens) {
cerr << "help!" << endl;
....
}
});
我认为你需要使用额外的括号来使你的表达式看起来像一个参数,它不会被预处理器分解,即更像这样:
#define MY_MACRO( (expr) ) DOSOMETHING( (expr) ); DOANOTHERTHING( (expr) ); // etc...
int my_function() {
MY_MACRO(
(int k = AFunction();
k++;
AnotherFunction( k );)
);
}
虽然我还没有尝试过。
在C ++中,你应该使用仿函数! ;)
struct ninja
{
void operator()() const
{
int k = AFunction();
k++;
AnotherFunction( k );
}
};
template <typename Functor>
void do_something(Functor const& f)
{
f();
}
template <typename Functor>
void do_otherthing(Functor const& f)
{
f();
}
int my_function()
{
ninja foo;
do_something(foo);
do_otherthing(foo);
}
我看到的主要问题是expr
根本不是表达。它甚至包含一个声明。显然,你会遇到k
中定义的两个变量my_function
的问题。
如果你可以使用C ++ 0x(例如VS2010,GCC4.6),那么你可以使用lambda来捕获上下文。并不是说您需要捕获这样一个简单案例的上下文,也不需要模板,您的宏只需要一个std::function<void(void)>
。
参数的多行宏也可以在多个参数的情况下使用,它甚至允许使用“逗号”,但我强烈建议使用“逗号”,因为如果它不是机器的模糊,它肯定是人类的模糊:
#include <iostream>
using namespace std;
#define MACRO2FUN( X, Y) x; y;
void function(int a, int b, int c){
std::cout<<a<<" "<<b<<" "<<c<<std::endl;
}
int main() {
MACRO2FUN(
function(3,4,5),
function(6,7,8)
)
return 0;
}
以上是关于具有多行参数的宏功能?的主要内容,如果未能解决你的问题,请参考以下文章