如何将参数的:: std :: vector绑定到仿函数? [英] How do I bind a ::std::vector of arguments to a functor?

查看:127
本文介绍了如何将参数的:: std :: vector绑定到仿函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图使该程序正确编译:

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::functions. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆