A simple way in C++11 is partial specialization with a variadic template:
template<class PMF> struct pmf_to_pf;
template<class R, class C, class... Args>
struct pmf_to_pf<R (C::*)(Args...)>{
using type = R(*)(Args...); // I like using aliases
};
Note that you need a seperate partial specialization for const
member-functions (and theoretically for ref-qualified ones aswell):
template<class R, class C, class... Args>
struct pmf_to_pf<R (C::*)(Args...) const>{
using type = R(*)(Args...);
};
With cv-qualifiers ({nil,const}
, {nil,volatile}
) and ref-qualifiers ({nil, &, &&}
), you have a total of 2*2*3 == 12
partial specializations to provide†. You normally can leave out the volatile
qualification ones, dropping the total down to "just" 6. Since most compilers don't support function-ref-qualifiers, you only need 2 really, but be aware of the rest.
For C++03 (aka compilers without variadic templates), you can use the following non-variadic form:
template<class PMF> struct pmf_to_pf;
template<class Sig, class C>
struct pmf_to_pf<Sig C::*>{
typedef Sig* type; // 'Sig' is 'R(Args...)' and 'Sig*' is 'R(*)(Args...)'
};
Although this doesn't quite work with cv-qualifiers, since I think C++03 didn't allow cv-qualified signatures (e.g. R(Args...) const
) on which you could partially specialize to remove the const
.
† The {...}
denote a set of a certain qualifier, with nil
representing the empty set. Examples:
void f() const&
would be {const}, {nil}, {&}
void f() &&
would be {nil}, {nil}, {&&}
And so on.