variadic模板参数包扩展函数调用

Kla*_*aus 17 variadic-templates c++11

我正在寻找类似的东西:

template< typename T>  
void func(T t)
{
}

template< typename... Parms> 
void anyFunc( Parms... p)
{
    func<Parms>(p)... ;  //error 
    func(p)... ;         //error 
}
Run Code Online (Sandbox Code Playgroud)

如果参数包扩展在另一个函数调用内完成,它可以工作:

template< typename T>
int some(T t)
{}

template< typename... Parms>
void func(Parms ...p)
{}

template< typename... Parms>
void somemore(Parms... p)
{
   func( some(p)...);
}

int main() 
{
 somemore(1,2,3,4,10,8,7, "Hallo");
}
Run Code Online (Sandbox Code Playgroud)

参数包扩展也适用于基类初始值设定项列表.

是否有任何解决方案也适用于将返回'void'的函数.上面的解决方法不会,虽然使用函数调用返回参数列表中的void可能永远不会工作.

有任何想法吗?

Joh*_*esD 10

不幸的是,正如您所注意到的,扩展参数包仅在某些上下文中有效,其中解析器需要以逗号分隔的条目列表 - 上下文中逗号只是语法分隔符,而不是逗号运算符.这可以说是目前案文中的一个缺陷.

一个丑陋的解决方法:

func((some(p), 0)...);
Run Code Online (Sandbox Code Playgroud)

请注意,函数参数的评估顺序以及some调用的顺序是未指定的,因此您必须小心任何副作用.

  • @ Peregring-lk:使省略号下的表达式`(some(p),0)`有一个非void类型 - 这是必需的,因为你需要一个有效的非void类型来传递给辅助函数`func` . (4认同)
  • `,0` 的用途是什么? (2认同)

Ker*_* SB 5

一个小助手班怎么样:

template <typename Func, typename A, typename ...Args> struct Caller
{
  static void call(Func & f, A && a, Args && ...args)
  {
    f(std::forward<A>(a));
    Caller<Func, Args...>::call(f, std::forward<Args>(args)...);
  }
};

template <typename Func, typename A> struct Caller<Func, A>
{
  static void call(Func & f, A && a)
  {
    f(std::forward<A>(a));
  }
};

template <typename Func, typename ...Args>
void Call(Func & f, Args && ...args)
{
  Caller<Func, Args...>::call(f, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以将以下内容放入客户端代码中:

void foo(A);
Call(foo, a1, a2, a3);
Run Code Online (Sandbox Code Playgroud)