只适用一次的宏

是否可以编写一个宏,无论嵌套多少次,它都只适用一次?

// how to implement this properly?
#define FOO(x) hello(x) // incorrect, works only for 1 level of nesting

// desired use below
void hello(int x);
FOO(x); // expanded to "hello(x)"
FOO(FOO(x)); // also expanded to "hello(x)", not "hello(hello(x))"
FOO(FOO(FOO(x))); // also expanded to "hello(x)"

是否有任何替代实现FOO,也许不是作为宏,而是一些可以达到相同效果的 C++ 模板?


为什么我需要这个?

我正在编写 clang libTooling 源到源转换,这些转换将一些变量使用包含在我自己的包装器中。例如,我有以下代码片段:a[3] = 5;

它被转化为hello(a)[3] = 5;,其意义和行为hello由我控制。但是,如果我有以下代码片段

#define A a[3] 
A = 4;
A = 5;
A = 6;

然后由于 clang libTooling 的限制,我必须像这样向宏主体添加更改:

#define A hello(a)[3] 
A = 4;
A = 5;
A = 6;

不幸的是,这并不容易实现,因为模式匹配了3次,一般情况下如何区分它们并不明显,所以一切都是这样结束的:

#define A hello(hello(hello(a)))[3] 
A = 4;
A = 5;
A = 6;

这显然不是我想要的,所以我正在寻找解决方法。我希望一些宏的设计FOO可以用最少的努力解决问题。

回答

您可以根据参数类型重载函数。使用特殊类型,您可以转发它,仅在提供实际参数时调用该函数。

void hello(int x);

struct FOO_hello_called {};
FOO_hello_called FOO(int x) {
   hello(x);
   return {};
}
FOO_hello_called FOO(FOO_hello_called s) {
   return s;
}

int main() {
    int x = 1;
    FOO(x); // calls "hello(x)"
    FOO(FOO(x)); // calls "hello(x)" once
    FOO(FOO(FOO(x))); // also calls "hello(x)" once
}


以上是只适用一次的宏的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>