Skip to main content
 首页 » 编程设计

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

2024年11月24日14itcoder

我需要获取一个大小为 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解释了如何做到这一点。