iggy
iggy

Reputation: 1743

C++11 variadic template parameter expansion

I would like to do the following:

template<typename Func>
class FunctionWrapper
{
public:
    typedef decltype(Func()) ReturnType;
    typedef ... ArgsType;

    FunctionWrapper(Func func)
    {
        func_ = func;
    }

    ReturnType operator() (ArgsType args)
    {
        return func_(args);
    }
private:
    Func func_;
};

The problem is I don't know how to deduce the ArgsType from Func type. I'd like to make it work when the function returns/accepts nothing as well.

The usecase would then be:

FunctionWrapper<myFunction> wrapper;
auto result = wrapper(1, 2, 3);

Upvotes: 1

Views: 92

Answers (2)

Columbo
Columbo

Reputation: 60969

You can determine the argument and return type(s) in operator() and use perfect forwarding:

template <typename Func>
class FunctionWrapper
{
    Func func_;

public:

    FunctionWrapper(Func func) : func_(func) {}

    template <typename... Args>
    auto operator() (Args&&... args)
      -> decltype(func_(std::forward<Args>(args)...)) {
        return    func_(std::forward<Args>(args)...);
    }
};

Upvotes: 1

Lingxi
Lingxi

Reputation: 14967

There is no generic way to do that, neither is it logical. Just think of the case when Func overloads operator() and accepts different argument types. You could, however, mandates that Func defines its argument type as a member type for utility like FunctionWrapper to access. See the possible member types of std::function for an example.

Upvotes: 0

Related Questions