user5570258
user5570258

Reputation: 33

how unpack tuple for wrapper function parameter in c++11?

//function wapper
template<class F,typename...Args>
class FuncWrapper
{
private:
    //F return type
    using return_type = typename std::result_of<F(Args...)>::type;

    template<int ...S> struct IndexSeq {};
    template<int N, int ...S> struct makeSeq : makeSeq<N - 1, N - 1, S...> {};
    template<int ...S> struct makeSeq<0, S...> : IndexSeq<S...> {};


public:
    FuncWrapper(F &&func,Args&&...args):
        f(std::move(std::function<return_type(Args...)>(std::forward<F>(func)))),
        para(std::make_tuple<Args...>(std::forward<Args>(args)...))
    {}
    ~FuncWrapper() = default;

    template <int... INDEX>
    return_type delay_action(makeSeq<INDEX...>)
    {
        return f(std::get<INDEX>(para)...);
    }

    //
    return_type operator()()
    {
        return  delay_action(makeSeq<sizeof...(Args)>{});
    }

private:
    //function
    std::function<return_type(Args...)> f;
    //parameter in the tuple
    std::tuple<Args...> para;
};

template<class F,typename ...Args>
FuncWrapper<F,Args...> make_function_wapper(F &&f, Args&&...args)
{
    return FuncWrapper<F, Args...>(std::forward<F>(f), std::forward<Args>(args)...);
}

here is the question : I want to create an template class for wrapper function , and use tuple for the parameter store , but it seems that it will not work well and I cannot find why. so I need some help and who can explain for it . thx for your help !

Upvotes: 0

Views: 285

Answers (1)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48527

The below code:

template <int... INDEX>
return_type delay_action(makeSeq<INDEX...>)
{
    return f(std::get<INDEX>(para)...);
}

should be:

template <int... INDEX>
return_type delay_action(IndexSeq<INDEX...>)
//                       ~~~~~~~^
{
    return f(std::get<INDEX>(para)...);
}

The idea behind the sequence generator that you use is that the most-derived makeSeq<2> class eventually inherits from IndexSeq<0, 1>, and what you want to be deduced is the series of numbers from IndexSeq, not the length of a sequence from makeSeq itself.

You should also note that Args in FuncWrapper can be of a (possibly cv-qualified) lvalue reference type, so to safely store the arguments in a tuple, the tuple declaration should be as follows:

std::tuple<typename std::decay<Args>::type...> para;
//                  ~~~~~~~~~^

Upvotes: 1

Related Questions