我正在努力应对具有挑战性但又简单的问题。 假设我有一个目标函数如下
void target_fnc(int arg1, double arg2)
{ /* do something here */ }
我想要“提取”的是变量名称(即'arg1','arg2')。 通过一些预处理获取变量的这些信息是微不足道的,例如
#define PRINTER(name) printer(#name)
void printer(const std::string& name) {cout << name << endl;}
我也可以在多个变量的情况下使用可变参数宏
#define PRINTER2(names...) printer(#names)
printer(arg1,arg2)
但我没有任何关于如何从目标函数“提取”的线索......例如,使用变量模板tecniques如下
template <typename ...A>
void extract(void (*)(A...))
{ printer(A...); }
它不起作用:我会获得'A ...'而不是解压缩的变量,当然...... 有什么提示吗?
谢谢! 注意:我正在使用C ++ 11,gcc 4.8.1
答案 0 :(得分:0)
CPP只是一个复制粘贴文本系统。它没有设法去做那种魔术。事实上,它只是愚蠢的“当你看到 X 时,把 Y ”操作。
在您的情况下,如果您尝试迭代可变参数包:
inline void print(const std::string& name) { std::cout << name << std::endl; }
#define PRINT(name) print(#name)
//Base case:
void extract() {}
//Recursive case:
template<typename HEAD , typename... TAIL>
void extract(const HEAD& head , const TAIL& tail...)
{
PRINT(head);
extract(tail...);
}
你只能得到:
头
头
头
头
...
答案是:避免将CPP用于愚蠢的事情,仅将其用于#ifdef #endif
标题保护和便携式编译。
请注意,不包括GET_GREATHER(x,y) ((x) > (y) ? (x) : (y))
之类的宏。 C ++从历史开始就成为避免使用宏的强大工具:内联函数
答案 1 :(得分:0)
执行编译步骤是有一个顺序的,而您想要的不是我们所拥有的。
首先执行预处理器;然后,完成后,C ++构建开始。模板化的东西正在构建时,并不能赋予它们提供预处理器的神奇能力,反之亦然。
是的,能够反映符号名称并对其进行字符串化和填充是一件很好的事情,但这必须从预处理器界面或使用生成器的预构建步骤中完成。
有大量的反思建议:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0255r0.pdf
或
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1240r0.pdf
在C ++中,但我不知道什么时候会发生。
否则,您可以尝试类似
的事情
http://pfultz2.com/blog/2012/07/31/reflection-in-under-100-lines/
REFLECTABLE
(
(const char *) name,
(int) age
)
int main()
{
Person p("Tom", 82);
print_fields(p);
return 0;
}