Quel est le problème avec ce pointeur à la conversion de membre?

Quel est le problème avec ce code? Je pensais pouvoir convertir grâce à cette réponse:

Est-il prudent de “surchauffer” un pointeur de méthode et de l’utiliser avec un pointeur de classe de base?

struct B { void f(){} }; struct D : B { virtual ~D(){} }; template  void g() { } int main() { g(); return 0; } 

Erreur:

 t.cpp:18:27: error: could not convert template argument '&B::f' to 'void (D::*)()' g(); 

Cela ne marche pas non plus:

 g<void (D::*)(), static_cast(&B::f)>(); 

Ceci est interdit par la norme (C ++ 11, [temp.arg.nontype] §5):

Les conversions suivantes sont effectuées sur chaque expression utilisée comme argument de modèle non typé. Si un argument de modèle non-type ne peut pas être converti en type du paramètre de modèle correspondant, le programme est mal formé.

  • Pour un paramètre template non-type de type pointeur vers une fonction membre, si l’ argument template est de type std::nullptr_t , la conversion de pointeur de membre null (4.11) est appliquée; sinon, aucune conversion ne s’applique . Si l’argument modèle représente un ensemble de fonctions de membre surchargées, la fonction de membre correspondante est sélectionnée dans l’ensemble (13.4).

(C’est moi qui souligne)

Les conversions ne sont pas autorisées non plus, à cause de [temp.arg.nontype] §1:

Un argument de modèle pour un paramètre de modèle non typé ou non template doit être l’un des suivants:

  • un pointeur sur membre exprimé comme décrit en 5.3.1.

Où 5.3.1§4 se lit comme suit:

Un pointeur sur membre n’est formé que lorsqu’un explicite & est utilisé et que son opérande est un identifiant qualifié non compris entre parenthèses.

Cela se combine pour dire qu’une experssion de cast n’est pas autorisée en tant qu’argument de modèle non typé.

Ainsi, bien que de telles conversions soient possibles à l’exécution, il semble qu’il n’y ait aucun moyen de les utiliser comme arguments de modèle.