将向量项传递给具有未知数量参数的函数对象

时间:2017-06-13 10:03:49

标签: c++ c++11

这是我想要实现的简化版本:

template <class Func, class Params>
void foo(Func f, Params p) {
  f(p[0], p[1], ...) // <-- this is the problem. How to do this?
}
...
foo([](int a, int b){ cout<<(a+b); }, std::vector<int>{1,2});
foo([](char a){ cout<<a; }, std::vector<char>{'a'});

我希望问题很清楚。

修改

上述例子没有很好地传达问题。我有一个参数的早期阶段填充的向量。我想要一个接受函数对象的函数,并使用向量中的参数调用它。我可以假设矢量大小等于参数的数量。

希望更好的例子:

class C {
  std::vector<int> v;
public:
  void add_param(int);
  ... // other functions that manipulate the vector in various ways

  template<class Func>
  void run(Func f) {
    f(v[0], etc...); // <-- problem
  }
};

2 个答案:

答案 0 :(得分:6)

您可以使用变量模板:

template <class Func, class... Params>
void foo(Func f, Params... p) {
  f(p...);
}

foo([](int a, int b){ cout<<(a+b); }, 1, 2);
foo([](char a){ cout<<a; }, 'a');

答案 1 :(得分:4)

您可以使用以下内容:

// Minimal traits to have information about function
template <typename Func> struct function_traits;

template <typename Ret, typename ... Ts>
struct function_traits<Ret (Ts...)>
{
    constexpr static auto arity = sizeof...(Ts);
};

template <typename Ret, typename ... Ts>
struct function_traits<Ret (*)(Ts...)> : function_traits<Ret(Ts...)> {};

template <typename C, typename Ret, typename ... Ts>
struct function_traits<Ret (C::*)(Ts...) const> : function_traits<Ret(Ts...)> {};

template <typename C>
struct function_traits : function_traits<decltype(&C::operator())> {};

namespace detail
{

    template <typename F, typename Vec, std::size_t ... Is>
    void call(const F& f, Vec&& v, std::index_sequence<Is...>)
    {
        f(v[Is]...);
    }
}


template <class Func, class Vec>
void foo(const Func& f, Vec&& v) {
    detail::call(f,
                 std::forward<Vec>(v),
                 std::make_index_sequence<function_traits<Func>::arity>());
}

Demo