调用功能的通用模板与向量元素

时间:2013-06-14 17:37:21

标签: c++ templates c++11

我想调用带有来自向量的参数的函数。仅这一点当然很容易,但我想写一个通用的包装器为我做任务。后来它也应该从类似boost :: variant的泛型类型进行转换,但我认为在解决这个问题后我可以处理它。

这是我的第一次尝试:

#include <iostream>
#include <functional>
#include <vector>

using namespace std;

void foo(int a, int b)
{
  cout << a*10+b << endl;
}

template<class... Args>
void callByVector(std::function<void(Args...)> f, vector<int>& arguments)
{
  int i = 0;
  f(static_cast<Args>(arguments[i++])...);
}

int main()
{
  vector<int> arguments;
  arguments.push_back(2);
  arguments.push_back(3);

  callByVector(std::function<void(int,int)>(foo),arguments);
}

它有效,但正如您可能猜到的,未定义增量的执行顺序。 因此,整体结果可以是23或32(我可以用不同的编译器确认)。

任何想法或我是否必须忘记这一点?

问候, 弗洛里安

1 个答案:

答案 0 :(得分:11)

您可以为此目的使用索引。给定这个编译时整数序列的生成器:

template<int... Is>
struct seq { };

template<int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };

template<int... Is>
struct gen_seq<0, Is...> : seq<Is...> { };

您可以让原始函数将工作委托给一个调用辅助函数,该函数使用一个允许推导整数序列的附加参数。参数包扩展将完成剩下的工作:

template<class... Args, int... Is>
void callByVector(
    std::function<void(Args...)> f, vector<int>& arguments, seq<Is...>)
{
  f(arguments[Is]...);
}

template<class... Args>
void callByVector(std::function<void(Args...)> f, vector<int>& arguments)
{
  callByVector(f, arguments, gen_seq<sizeof...(Args)>());
}

这是live example