【发布时间】:2019-09-22 14:18:02
【问题描述】:
我需要获取一个大小为 n 的输入参数数组并将其值绑定到另一个接受 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;
}
【问题讨论】:
-
您的意思是“递归”还是迭代?因为这些不是同一个词,并且含义大不相同,而且您发布的代码使用迭代而不是递归。事实上,使用实际递归可能会容易得多。
-
另外,
n是编译时定义的还是运行时定义的?因为后者实际上是不可能的(或者至少,不容易做到)。 -
我的意思是迭代,但也可以接受递归解决方案。 N 是定义的编译时间。