展开Vardiadic宏中的Variadic模板(如何从目标函数中提取参数名称)

时间:2013-07-02 09:31:10

标签: c++ variadic-templates template-meta-programming variadic-macros preprocessor-meta-program

我正在努力应对具有挑战性但又简单的问题。 假设我有一个目标函数如下

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

2 个答案:

答案 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;
}