可变调度函数

Variadic Dispatch Function

我有一个接口,其中参数的类型主要编码它们自己的含义。我有一个采用这些参数之一的函数。我正在尝试制作一个函数,该函数采用一组这些参数并按顺序对每个参数执行函数。

#include <iostream>
#include <vector>

enum param_type{typeA,typeB};

template <param_type PT> struct Container{
  int value;
  Container(int v):value(v){}
};

int f(Container<typeA> param){
  std::cout<<"Got typeA with value "<<param.value<<std::endl;
  return param.value;
}
int f(Container<typeB> param){
  std::cout<<"Got typeB with value "<<param.value<<std::endl;
  return param.value;
}

我当前的解决方案使用递归可变参数模板来委派工作。

void g(){}
template <typename T,typename...R>
void g(T param,R...rest){
  f(param);
  g(rest...);
}

我想使用压缩参数扩展,但如果不同时使用 return 值,我似乎无法让它工作。 (在我的特殊情况下,函数无效。)

template <typename...T> // TODO: Use concepts once they exist.
void h(T... params){
  // f(params);...
  // f(params)...;    // Fail to compile.
  // {f(params)...};
  std::vector<int> v={f(params)...}; // Works
}

用法示例

int main(){
  auto a=Container<typeA>(5);
  auto b=Container<typeB>(10);
  g(a,b);
  h(a,b);
  return 0;
}

在 C++ 中是否有这种扩展的优雅语法?

在 C++17 中:使用带逗号运算符的折叠表达式。

template <typename... Args>
void g(Args... args)
{
    ((void)f(args), ...);
}

C++17 之前:用 0 逗号,然后扩展到 int 数组的花括号初始化列表中。额外的 0 是为了确保不会创建零大小的数组。

template <typename... Args>
void g(Args... args)
{
    int arr[] {0, ((void)f(args), 0)...};
    (void)arr;                            // suppress unused variable warning
}

在这两种情况下,函数调用表达式都被强制转换为 void 以避免意外调用用户定义的 operator,.