Reputation: 3145
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
Reputation: 170055
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
.
Upvotes: 2