我想调用带有来自向量的参数的函数。仅这一点当然很容易,但我想写一个通用的包装器为我做任务。后来它也应该从类似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(我可以用不同的编译器确认)。
任何想法或我是否必须忘记这一点?
问候, 弗洛里安
答案 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。