Une façon simple en C++ 11 est une spécialisation partielle avec un modèle variadique:
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
};
Notez que vous avez besoin d'une spécialisation séparée partielle pour const
membres-fonctions (et théoriquement pour les ref-qualified aswell):
template<class R, class C, class... Args>
struct pmf_to_pf<R (C::*)(Args...) const>{
using type = R(*)(Args...);
};
Avec cv-qualifiés ({nil,const}
, {nil,volatile}
) et ref-qualificatifs ({nil, &, &&}
), vous avez un total de 2*2*3 == 12
spécialisations partielles pour fournir †. Vous pouvez normalement omettre les qualifications de volatile
, en réduisant le total à "juste" 6. Puisque la plupart des compilateurs ne supportent pas les qualificatifs de fonction-ref, vous en avez vraiment besoin de 2, mais soyez conscient du reste.
Pour 03 C++ (compilateurs aka sans modèles variadique), vous pouvez utiliser le formulaire non variadic suivant:
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...)'
};
Bien que cela ne fonctionne pas tout à fait avec des qualificatifs de cv, depuis Je pense que C++ 03 n'a pas permis les signatures qualifiées cv (par exemple R(Args...) const
) sur lesquelles vous pourriez vous spécialiser partiellement pour supprimer le const
.
† Le {...}
représentent un ensemble d'une certaine qualification, avec nil
représentant l'ensemble vide. Exemples:
void f() const&
seraient {const}, {nil}, {&}
void f() &&
serait {nil}, {nil}, {&&}
Et ainsi de suite.
@Xeo Merci! Je le marquerais comme une réponse, mais vous avez seulement posté un commentaire :) –
Il était incomplet et supposé C++ 11, mais je l'ai étoffé dans une réponse maintenant. – Xeo