c++ - 如何递归地将参数绑定(bind)到函数?

标签 c++ c++11

我需要获取一个大小为 n 的输入参数数组,并将其值绑定(bind)到另一个接受 n 个参数的函数。

我尝试使用 bind 将数组的元素一一传递给函数,但它不起作用(有点像在循环中使用 bind_front )。

我需要的是这样的:

#include <iostream>
#include <functional>


using namespace std;

int addThreeNumbers(int a, int b, int c)
{
    return a+b+c;
}

int main()
{
    int parameters[] = {1, 2, 3};

    auto f = addThreeNumbers;

    // Bind each element from the list one by one
    for(int i=1; i<parametersLength; i++)
    {
         f = bind(f, parameters[i]);
    }

    f(); // call addThreeNumbers

    return 0;
}

该解决方案需要使用任意大小的数组的参数。
使用 c++ 11 可以做到这一点吗?

编辑

感谢 Aconcagua 和 Philipp Lenk,我得到了它的工作!
这是工作代码:
#include <iostream>
#include <functional>


using namespace std;

// index sequence only
template <size_t ...>
struct indexSequence
 { };

template <size_t N, size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...>
 { };

template <size_t ... Next>
struct indexSequenceHelper<0U, Next ... >
 { using type = indexSequence<Next ... >; };

template <size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;

int addThreeNumbers(int a, int b, int c)
{
    return a+b+c;
}


template <typename F, typename T, size_t N, size_t ... I>
auto dispatch(F function, T(&array)[N], indexSequence<I ...>) -> decltype(function(array[I]...))
{
    return function(array[I]...);
}

template <typename F, typename T, size_t N>
auto dispatch(F function, T(&array)[N]) -> decltype(dispatch(function, array, makeIndexSequence<N>()))
{
    return dispatch(function, array, makeIndexSequence<N>());
}


int main()
{
    int a[] = { 1, 2, 3 };
    int s = dispatch(addThreeNumbers, a);

    cout << s << endl;

    return 0;
} 

编辑2

也可以使用元组来工作:
#include <iostream>
#include <tuple>
#include <string>


using namespace std;


// index sequence only
template <size_t ...>
struct indexSequence
 { };

template <size_t N, size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...>
 { };

template <size_t ... Next>
struct indexSequenceHelper<0U, Next ... >
 { using type = indexSequence<Next ... >; };

template <size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;


template <class F, class Tuple, std::size_t... Is>
constexpr auto apply_impl(const F& f, Tuple t, indexSequence<Is...>) -> decltype(f(std::get<Is>(t)...))
{
    return f(std::get<Is>(t)...);
}

template <class F, class Tuple>
constexpr auto apply(const F& f, Tuple t) -> decltype(apply_impl(f, t, makeIndexSequence<std::tuple_size<Tuple>{}>{}))
{
    return apply_impl(f, t, makeIndexSequence<std::tuple_size<Tuple>{}>{});
}


int sum(int a, int b, string c)
{
    cout << c << endl;
    return a+b;
}


int main()
{
    auto parameters = std::make_tuple(1,2,"1+2=3");

    int s = apply(sum, parameters);

    cout << s << endl;

    return 0;
}

最佳答案

如果我没看错您的问题,您实际上打算将数组分解为单个参数。如果是这样,您可以使用 std::index_sequence :

template <typename F, typename T, size_t N, std::size_t ... I>
auto dispatch(F function, T(&array)[N], std::index_sequence<I ...>)
{
    return function(array[I]...);
}

template <typename F, typename T, size_t N>
auto dispatch(F function, T(&array)[N])
{
    return dispatch(function, array, std::make_index_sequence<N>());
}

使用示例:
int sum(int a, int b, int c)
{
    return a + b + c;
}

int a[] = { 1, 2, 3 };
int s = dispatch(sum, a);

当然,如果数组长度和函数参数的数量不匹配,你会得到一个编译错误......

编辑:作为 std::index_sequence在 C++14 之前不可用,您可以实现自己的变体。 This answer解释了如何做到这一点。

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

相关文章:

c++ - 实现纯虚方法后 vtable C++ 错误

c++ - curl - PROTOCONNECT 属于什么超时

c++ - 如何使用 decltype 作为模板类返回类型的模板参数?

c++ - move 构造函数和 char 数组参数

c++ - 与相应的 cpp 代码相比,为什么这个 bash 代码这么慢?

c++ - Bison 解析器 : making a function which is returning tokens

c++ - 有没有一种方法可以编写一个宏来仅使用变量名(即等同于 std::forward<T>(t) 的 FWD(t))进行完美转发?

c++ - 知道为什么 std::move 在这里失败了吗?

c++ - 返回(大)对象时复制开销?

c++ - 基于C++ CRTP的数据流输出类设计简化