Peter
Peter

Reputation: 3145

Deduce parameter type of pointer to member function template parameter

I'm trying to write a C++ function template f with one template parameter of type void (Foo::*FUNC)(T const *) where Foo is some class type. Furthermore, I would like to deduce T from the concrete member function pointer specified for FUNC. So one idea would be:

template<typename T, void(Foo::*FUNC)(T const *)>
void f()
{ /* use T in here, e.g. if constexpr (std::is_same_v<T, int>) */ }

But then I have to specify T explicitly when instantiating f and can't just write e.g. f<&Foo::bar>. I know there are ways to deduce the type of the first parameter of a function but they are all overly complicated (without using Boost). Is there a smarter way to do what i want?

Upvotes: 2

Views: 658

Answers (1)

Here's a trait to extract an argument from a member function pointer that looks like you expect it to look:

namespace detail {
    template<typename M> struct extract_arg;
    template<typename R, class C, typename A>
    struct extract_arg<R (C::*)(A const*)> { using type = A; }
}

And here's a C++17 function template with a non-type template parameter whose type is deduced from a placeholder:

template<auto FUNC>
void f()
{
    static_assert(std::is_member_function_pointer_v<decltype(FUNC)>);
    using T = typename detail::extract_arg<decltype(FUNC)>::type;
    T t{};
}

It uses std::is_member_function_pointer to check its indeed of the correct type (well, family of types), and our helper trait to then extract T.

See it live.

Upvotes: 2

Related Questions