gpt4 book ai didi

c++ - 如何将参数的 a::std::vector 绑定(bind)到仿函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:15:08 25 4
gpt4 key购买 nike

我正在努力让这个程序正确编译:

#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 中提取函数参数。

这不是它的最终用途,但它是通往我想去的地方的垫脚石。我真正在做的是生成包装函数,在编译时将它们的参数从 future / promise 类型系统中的 promise 中解开。这些包装函数本身就是 promise 。

在我的最终用例中,我可以指望仿函数是 ::std::function。但如果能知道它应该如何适用于更一般的仿函数,那将是一件好事,因为我认为这是一个广泛有趣的问题。

最佳答案

好的,首先,可以检测仿函数的元数,但这有点复杂,最好留给一个单独的问题。假设您将在调用中指定仿函数的元数。同样,有一些方法可以获得可调用对象的返回类型,但这也超出了这个问题的范围。我们现在假设返回类型是 void

所以我们想说,

call(F f, C v);

应该是 f(v[0], v[1], ..., v[n-1]),其中 f 有元数 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);
}

我们需要 helper :

#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 限定的类成员函数进行一些专门化,因此对于这个问题来说这会变得太大了。

关于c++ - 如何将参数的 a::std::vector 绑定(bind)到仿函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13594721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com