只适用一次的宏
是否可以编写一个宏,无论嵌套多少次,它都只适用一次?
// 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
}