C ++ Macro Magic:获取每个宏参数,参数计数

时间:2015-05-20 09:10:58

标签: c++ macros

我写了很多像这样的代码。

foo.setArg(0, arg_0);
foo.setArg(1, arg_1);
...
foo.setArg(n, arg_n);

其中n是特定于编译时的,而arg_n是不同类型的;

我想要一个可变的宏,我可以像这样调用它     MACRO_MAGIC(arg_0,arg_1,...,arg_n)

我知道如何获得参数总数,但我没有成功管理它。

来自(无意义)语句的

编辑: n是特定于编译时的运行时

3 个答案:

答案 0 :(得分:1)

您可以使用可变参数模板:

namespace detail
{
    template <std::size_t ... Is, typename ... Ts>
    void SetFoo(Foo& foo, std::index_sequence<Is...>, Ts&&... args)
    {
        int dummy[] = {0, (foo.setArg(Is, args), void(), 0)...};
        (void) dummy; // Remove warning for unused variable
    }
}

template <typename ... Ts>
void SetFoo(Foo& foo, Ts&&... args)
{
    detail::SetFoo(foo, std::index_sequence_for<Ts...>(), std::forward<Ts>(args)...);
}

Live Demo

或使用C ++ 17,使用折叠表达式:

namespace detail
{
    template <std::size_t ... Is, typename ... Ts>
    void SetFoo(Foo& foo, std::index_sequence<Is...>, Ts&&... args)
    {
        (static_cast<void>(foo.setArg(Is, args)), ...);
    }
}

答案 1 :(得分:0)

有时,我似乎也必须编写这样的代码,但幸运的是我很快就会找到替代方案。在那些我不知道的情况下,我(本地!)构建这样的宏(以防止复制粘贴错误):

#define SET_FOO(num) foo.setArg(num, arg_##num);
SET_FOO(1)
SET_FOO(2)
#undef SET_FOO

是的:它相当原始,绝对没有火箭安全,但它有帮助。

答案 2 :(得分:0)

我自己找到了答案:

#define IT_CHOOSER2(name,count) name##count
#define IT_CHOOSER1(name,count) IT_CHOOSER2(name,count)
#define IT_CHOOSER(name,count)  IT_CHOOSER1(name,count)

#define IT_SET_ARGS_PREFIX IT_SET_ARGS_
#define IT_SET_ARGS_1( foo, arg_1) kernel.setArg(0, arg_1)
#define IT_SET_ARGS_2( foo, arg_1, arg_2) kernel.setArg(0, arg_1); kernel.setArg(1, arg_2)

...

#define IT_SET_ARGS(foo,...)\
IT_GLUE(IT_CHOOSER(IT_SET_ARGS_PREFIX,IT_N_ARGS(__VA_ARGS__)), (kernel,__VA_ARGS__))

但我想提一下,如果c ++ 11可用,Jarod42解决方案要好得多。