【问题标题】:Passing variable arguments in a C++ variadic template在 C++ 可变参数模板中传递可变参数
【发布时间】:2012-12-29 00:02:25
【问题描述】:

假设我有一个模板函数,它接受可变参数并使用这些参数调用其他函数...

template<typename... A> func(int i, A... args)
{
  // do something common

  switch (i)
  {
    case 0: x(args...); break;
    case 1: y(args...); break;
    case 2: z(args...); break;

    default: break; 
  }

  // do something common
}

...其他函数定义为...

void x(int a, int b);
void y(int a, int b);  // note: takes same args as x()
void z(std::string a);

这不会编译,因为使用 std::string 参数调用 func() 将找不到与带有 std::string 参数的 x() 和 y() 的匹配项。

请注意,func() 使用一些外部标准(本示例中的参数 i 的值)来决定将参数 args 传递给哪个其他函数。

有没有办法在不诉诸诸如将参数 args 填充到 std:tuple 中并传递它的情况下实现这一目标?

[编辑]

好的,我想出了一种对我的目的来说效果很好的方法。这是一个示例类来说明...

class X
{
  private:

    bool a(int) { return true; }
    bool b(int) { return true; }

    template<typename... A> bool a(const A&...) { return false; }
    template<typename... A> bool b(const A&...) { return false; }

  public:

    template<typename... A> void x(int i, const A&... args)
    {
        if (i == 0)
        {
            a(args...);
        }
        else
        {
            b(args...);
        }
    }
};

a() 和 b() 的可变参数模板方法将捕获对参数不是单个 int 的 X.x() 进行的任何调用。这解决了我收到的编译器错误,并启用了我正在寻找的更简单的类 API。

【问题讨论】:

  • 你必须使用专业化/SFINAE。

标签: c++ templates variadic


【解决方案1】:

看看这个帖子我知道你可以使用...作为参数来告诉你使用的是可变数量的参数。

... syntax in C++

这是另一个带有良好注释代码的示例: Functions with Variable Argument Lists in C and C++ using va_list

我希望这会有所帮助。

【讨论】:

  • 啊。请不要在 C++ 问题上发布va_list永远
  • @BartekBanachewicz 你能解释一下你的顾虑吗?
  • @user1715664 你觉得我上面发布的解决方案怎么样?
  • 网络上有许多资源可以更好地向您解释。应该立即引起您注意的是它也在 C 中。
  • @BartekBanachewicz 在我在网上看到的所有示例中,它表明它可以在 c/c++ 中工作,这可能是一种糟糕的做事方式,但这是语言的一部分,人们仍在使用它,如果你有缺点,你可以提及它们,你的 cmets 可能对观众更有利。
【解决方案2】:

是的,进行单独的重载:

template <typename A1>
func(A1 arg1)
{
    x(arg1);
}

template <typename A1, typename A2>
func(A1 arg1, A2 arg2)
{
    y(arg1, arg2);
}

template <typename A1, typename A2, typename A3>
func(A1 arg1, A2 arg2, A3 arg3)
{
    z(arg1, arg2, arg3);
}

(当然,任何额外的通用代码都可以分解为单独的通用函数,可能是可变参数函数模板。)

【讨论】:

  • 不是我想要的,但没有提供足够的信息是我的错。 func() 可以调用其他采用相同参数类型的方法(例如,a(int) 和 b(int)),但根据其他标准(例如,i 的值)决定调用哪个方法。我将编辑问题以清除它。
  • 我的用例是一个状态机,其中传入了一个事件类型及其数据。根据当前状态和事件类型,调用适当的事件处理程序来处理数据并可能推进状态机。
  • @user1715664:这听起来更像是一个动态问题,而不是静态问题。
猜你喜欢
  • 2014-10-20
  • 2016-12-01
  • 1970-01-01
  • 2016-05-08
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 2018-10-22
相关资源
最近更新 更多