如何将参数的:: std :: vector绑定到仿函数? [英] How do I bind a ::std::vector of arguments to a functor?
问题描述
我正试图使该程序正确编译:
I'm trying to make this program compile properly:
#include <vector>
#include <iostream>
int f(int a, int b)
{
::std::cout << "f(" << a << ", " << b << ") == " << (a + b) << '\n';
return a + b;
}
template <typename R, typename V>
R bind_vec(R (*f)(), const V &vec, int idx=0)
{
return f();
}
template <typename R, typename V, typename Arg1, typename... ArgT>
R bind_vec(R (*f)(Arg1, ArgT...), const V &vec, int idx=0)
{
const Arg1 &arg = vec[idx];
auto call = [arg, f](ArgT... args) -> R {
return (*f)(arg, args...);
};
return bind_vec(call, vec, idx+1);
}
int foo()
{
::std::vector<int> x = {1, 2};
return bind_vec(f, x);
}
理想情况下,我想要 bind_vec
可以将任意函子作为参数,而不仅仅是函数指针。这个想法是在编译时从 :: std :: vector
中提取函数参数。
Ideally I'd like bind_vec
to take an arbitrary functor as an argument instead of just a function pointer. The idea is to pull the function arguments from a ::std::vector
at compile time.
并非最终用途,但这是我要去的垫脚石。我真正在做的是生成包装器函数,以便在编译时将它们的参数从promise中的promise中删除。这些包装函数本身就是承诺。
This isn't the final use for this, but it's a stepping stone to where I want to go. What I'm really doing is generating wrapper functions that unwrap their arguments from promises in a future/promise type system at compile time. These wrapper functions will themselves be promises.
在我的最终用例中,我可以指望函子是 :: std :: function
s。但是,最好也知道如何在更一般的函子上工作,因为我认为这是一个非常有趣的问题。
In my ultimate use-case I can count on the functors being ::std::function
s. But it would be nice to have an idea of how it should work for more general functors as well since I think this is a broadly interesting problem.
推荐答案
好,首先,可以检测函子的奇偶性,但这涉及到一点,最好留给一个单独的问题。假设您将在通话中指定函子的Arity。同样,有一些方法可以获取可调用对象的返回类型,但这也超出了此问题的范围。我们现在假设返回类型为 void
。
OK, first off, detecting the arity of a functor can be done, but it's a bit involved and best left to a separate question. Let's assume you will specify the arity of the functor in the call. Similarly, there are ways to obtain the return type of a callable object, but that's also beyond the scope of this question. Let's just assume the return type is void
for now.
所以我们要说,
call(F f, C v);
,应该说 f(v [0],v [1] ,...,v [n-1])
,其中 f
的友善度是 n
。
and that should say f(v[0], v[1], ..., v[n-1])
, where f
has arity n
.
这里是一种方法:
template <unsigned int N, typename Functor, typename Container>
void call(Functor const & f, Container const & c)
{
call_helper<N == 0, Functor, Container, N>::engage(f, c);
}
我们需要帮助者:
#include <functional>
#include <cassert>
template <bool Done, typename Functor, typename Container,
unsigned int N, unsigned int ...I>
struct call_helper
{
static void engage(Functor const & f, Container const & c)
{
call_helper<sizeof...(I) + 1 == N, Functor, Container,
N, I..., sizeof...(I)>::engage(f, c);
}
};
template <typename Functor, typename Container,
unsigned int N, unsigned int ...I>
struct call_helper<true, Functor, Container, N, I...>
{
static void engage(Functor const & f, Container const & c)
{
assert(c.size() >= N);
f(c[I]...);
}
};
示例:
#include <vector>
#include <iostream>
void f(int a, int b) { std::cout << "You said: " << a << ", " << b << "\n"; }
struct Func
{
void operator()(int a, int b) const
{ std::cout << "Functor: " << a << "::" << b << "\n"; }
};
int main()
{
std::vector<int> v { 20, 30 };
call<2>(f, v);
call<2>(Func(), v);
}
注意:在更高级的版本中,我会用更多的模板机制来推导可调用对象的稀疏性,我也会推导返回类型。要使此功能有效,您将需要一些专门的免费功能和各种具有CV资格的类成员函数,因此对于这个问题来说,这将变得太大。
Notes: In a more advanced version, I would deduce the arity of the callable object with some more template machinery, and I would also deduce the return type. For this to work, you'll need several specializations for free functions and various CV-qualified class member functions, though, and so this would be getting too large for this question.
这篇关于如何将参数的:: std :: vector绑定到仿函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!