9

I would like to call a function with the arguments coming from a vector. This alone is certainly very easy, but I would like to write a generic wrapper that does the assignment for me. Later it should also do the conversion from a generic type like boost::variant, but I think I can handle that after this problem is solved.

This is my first try:

#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);
}

It works, but as you might guess, the order of execution of the increments is not defined. Therefore, the overall result can be 23 or 32 (I can confirm that with different compilers).

Any ideas or do I have to forget about that?

Greetings, Florian

4

1 回答 1

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)>());
}

这是一个活生生的例子

于 2013-06-14T17:43:41.497 回答