Un membre statique privé peut-il être utilisé comme argument par défaut d’une fonction membre de sa classe?

Lequel des compilateurs a raison?

class A { public: template  void fun(void (*f)() = funPrivate) {} private: template  static void funPrivate() {} }; int main(int argc, char** argv) { A a; a.fun(); return 0; } 

Comstack bien sur: gcc version 4.8.5 (Ubuntu 4.8.5-2ubuntu1 ~ 14.04.1)

Résultats en erreur sur: version clang 3.4-1ubuntu3 (tags / RELEASE_34 / final) (basé sur LLVM 3.4)

  a.cpp:5:27: error: 'funPrivate' is a private member of 'A' void fun(void (*f)() = funPrivate) {} ^~~~~~~~~~~~~ a.cpp:14:3: note: in instantiation of default function argument expression for 'fun' required here a.fun(); ^ a.cpp:8:16: note: declared private here static void funPrivate() {} ^ 1 error generated. 

§ 11

8 Les noms dans un argument par défaut (8.3.6) sont liés au sharepoint déclaration et l’access est vérifié à ce point plutôt qu’à tout point d’utilisation de l’argument par défaut. La vérification d’access pour les arguments par défaut dans les modèles de fonction et dans les fonctions membres des modèles de classe est effectuée comme décrit au 14.7.1.

§ 14.7.1

12 Si un modèle de fonction f est appelé de manière à nécessiter l’utilisation d’un argument par défaut, les noms dépendants sont recherchés, les contraintes de sémantique sont vérifiées et l’instanciation de tout modèle utilisé dans l’argument par défaut est effectuée argument était un initialiseur utilisé dans une spécialisation de modèle de fonction avec la même étendue, les mêmes parameters de modèle et le même access que celui du modèle de fonction f utilisé à ce stade. Cette parsing est appelée instanciation d’argument par défaut . L’argument instancié par défaut est ensuite utilisé comme argument de f .

Donc, je suppose que l’interprétation de gcc est juste. fun a access aux membres privés, ses arguments par défaut doivent donc être pris en compte dans le même access. Mais je lis entre les lignes que 14.7.1 (12) s’applique aux modèles de membre, et pas seulement aux modèles de fonction. De plus, il se peut que je comprenne mal que 14.7.1 (12) signifie.

J’ai testé le code dans msvc13. Ce code fonctionne:

 class A { template  static void funPrivate() {} public: template  void fun(void (*f)() = funPrivate) {} };