解包函数调用的参数数组

时间:2018-02-07 05:36:41

标签: c++ c++11 variadic-functions function-call

是否可以将函数及其参数列表传递给另一个函数并稍后从内部调用它?

void testA(int, float, char* ) {}
void testB(int, float, double ) {} 
void testC(MyClass, float, double ) {} 

template <class T>
void applyA(void(*foo)(void*), std::initializer_list<T> args)
{
    foo(/*unpack args somehow*/);
}

template <class T>
void applyB(void(*foo)(void*), std::initializer_list<T> args)
{
    MyClass cls;
    foo(cls, /*unpack the rest of args*/);
}

int main()
{
    applyA(testA, {5, 0.5f, "abc"});
    applyA(testB, {5, 0.5f, 1.5});
    applyB(testC, {0.5f, 1.5});
}

2 个答案:

答案 0 :(得分:3)

您可以在不使用数组的情况下转发参数,也可以使用the union之类的元组。

#include <vector>

class MyClass {};

void testA(int, float, const char* ) {}
void testB(int, float, double ) {} 
void testC(MyClass, float, double ) {} 

template <class T, typename... Args>
void applyA(T&& foo, Args... args)
{
    foo(args...);
}

template <class T, typename... Args>
void applyB(T&& foo, Args... args)
{
    MyClass cls;
    foo(cls, args...);
}

int main()
{
    applyA(testA, 5, 0.5f, "abc");
    applyA(testB, 5, 0.5f, 1.5);
    applyB(testC, 0.5f, 1.5);

    return 0;
}

std::apply() std::apply()

的示例
#include <tuple>

...
std::apply(testA, std::make_tuple(5, 0.5f, "abc"));
std::apply(testB, std::make_tuple(5, 0.5f, 1.5));
std::apply(testC, std::make_tuple(MyClass{}, 0.5f, 1.5));

自制apply()

的示例

SO "unpacking" a tuple to call a matching function pointer {/ 3}}的帮助下。

template<int ...>
struct seq { };

template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };

template<int ...S>
struct gens<0, S...> {
  typedef seq<S...> type;
};


template<typename F, typename Tuple, int... S>
void my_apply_impl(F&& func, Tuple&& params, seq<S...> ) {
    func(std::get<S>(std::forward<Tuple>(params)) ...);
}

template<typename F, typename Tuple>
void my_apply(F&& func, Tuple&& params) {
    my_apply_impl(std::forward<F>(func), std::forward<Tuple>(params), typename gens<std::tuple_size<Tuple>::value>::type() );
}

...
my_apply(testA, std::make_tuple(5, 0.5f, "abc"));
my_apply(testB, std::make_tuple(5, 0.5f, 1.5));
my_apply(testC, std::make_tuple(MyClass{}, 0.5f, 1.5));

answer

答案 1 :(得分:0)

上一个必须将answer函数更新为使用std :: decay,以便它也可以接受const元组(下面的更新部分):

template<typename F, typename Tuple>
void my_apply(F&& func, Tuple&& params)
{
    tuples::my_apply_impl(std::forward<F>(func), std::forward<Tuple>(params), typename tuples::gens<std::tuple_size<typename std::decay<Tuple>::type>::value>::type());
}