Search code examples
c++templatesfunctorperfect-forwarding

Perfect forwarding a functor


I wonder what's the right way of using a perfect forwarded functor? Here's two code snippet. Which one is the best, and if neither, what is the best form?

template<typename T, typename... Args>
void callMe(T&& func, Args&&... args) {
    func(std::forward<Args>(args)...);
}

Or

template<typename T, typename... Args>
void callMe(T&& func, Args&&... args) {
    std::forward<T>(func)(std::forward<Args>(args)...);
}

EDIT:

Will it impact overload resolution? If func's operator() has ref-qualifier for && or const &, should I do the latter version and should I care about which overload I call?

Thanks!


Solution

  • Since ref-qualified operator() exists, the first version could do the wrong thing. Consider:

    struct C {
        void operator()() && { std::cout << "rval\n"; }
        void operator()() const & { std::cout << "lval\n"; }
    };
    
    callMe(C{});
    

    I'm giving you an rvalue - and would expect to see "rval" - but in the first version, you're always treating the function object like an lvalue - so I really see "lval".

    So the correct solution would be the second - which forwards func as well.


    In practice, I don't know how often ref-qualified member functions actually happen, so the former is likely fine.