Search code examples
c++templatesc++11c++14functor

C++ use function argument type for template argument deduction


template<typename T>
void f(void (*func)(const T&)) {
    (*func)(T());
}

void func(const int& i) {
    std::cout << i << std::endl;
}

int main() {
    f(&func);
}

Here the template argument T (= int) of f is automatically deducted based on the first argument of the function func.

Can this also be extended to work with general functors (lambda functions or other function objects.) Possibly with a second function, i.e. something like

template<typename T, typename Function> void f(Function func);

template<typename Function>
void call_f(Function func) {
    using arg_type = first_argument_type_t<Function>; // ???
    f<arg_type, Function>(func);
}

The fall to func in f should be able to be inlined by the compiler, so std::function cannot be used.


Solution

  • I usually use function traits code like this (GPL-3 licensed) to do that:

    template <typename F>
    using first_argument_type_t =
         typename sharemind::FunctionTraits<F>::template argument<0u>::type;
    

    But there's also the Boost function_traits alternative, which might be of help.