Pourquoi ce modèle variadic nested est-il un argument non valide?

Si je définis un modèle de struct Bar qui accepte un argument de modèle:

 template <template  class> struct Bar {}; 

Je peux l’instancier en utilisant un template struct tel que Zod :

 template  struct Zod {}; Bar a; 

Je peux aussi l’instancier en utilisant un modèle de struct nested tel que JKL :

 struct GHI { template  struct JKL {}; }; Bar  b; 

Pourquoi ne puis-je pas instancier Bar utilisant un modèle de struct variadic nested tel que DEF ?:

 template  struct ABC { template  struct DEF {}; }; Bar<ABC::DEF> c; 

G ++ 4.9.2 se plaint d’une incompatibilité type / valeur; Tandis que l’erreur de Clang 3.4.2 indique que l’argument du modèle de modèle a des parameters de modèle différents de ceux du paramètre de modèle de modèle correspondant.

    Donnons un nom au pack de parameters de DEF pour faciliter la référence:

     template  struct ABC { template  struct DEF {}; }; 

    Le point clé ici est que par [temp.param] / p15, Ts... Values est à la fois une extension de pack de Ts et une déclaration de pack de parameters Values .

    Si un paramètre de modèle est une déclaration de paramètre qui […] déclare un pack de parameters (8.3.5), le paramètre template est un pack de parameters de modèle (14.5.3). Un pack de parameters de modèle qui est une déclaration de paramètre dont le type contient un ou plusieurs packs de parameters non développés est une extension de pack.

    Étant donné que DEF prend un paquet de parameters non-typés, il ne correspond pas à un paramètre de modèle de modèle qui ne prend pas les packs ([temp.arg.template] / p3):

    Un argument de modèle correspond à un paramètre de modèle de modèle P lorsque chacun des parameters de modèle de la liste de parameters de modèle du modèle de classe ou du modèle d’alias correspondant à l’argument template correspond au paramètre de modèle correspondant dans la liste de parameters de modèle. de P. Deux parameters de modèle correspondent s’ils sont du même type (type, non-type, modèle), pour les parameters de type non-type s, leurs types sont équivalents (14.5.6.1) et pour les parameters de modèle de modèle s , chacun de leurs parameters de modèle correspondants s correspond, récursivement. Lorsque la liste de parameters de modèle de P contient un paquet de parameters de modèle (14.5.3), le paquet de parameters de modèle correspond à zéro ou plusieurs parameters de modèle ou paquets de parameters de modèle dans la liste de parameters de modèle de A avec le même type et la même pack de parameters de modèle dans P (en ignorant si ces parameters de modèle sont des packs de parameters de modèle).

    Certes, Values est plutôt étrange pour les packs – pour chaque spécialisation de ABC , les Values doivent contenir un nombre fixe d’arguments – mais selon les règles actuelles, il s’agit toujours d’un pack, donc les règles pour les packs s’appliquent.

    Comme Barry l’a déjà dit à propos de:

     ABC::DEF<4,true,'c'> foo 

    Et faire un essai et a travaillé sur le compilateur en ligne Coliru gcc 5.1 c ++ 14 dans ce site Comstackr :

     #include  template  

    J’ai effectué une recherche et trouvé cette liste de parameters Template.

    L’expansion du pack peut apparaître dans une liste de parameters de modèle:

      template struct value_holder { template // expands to a non-type template parameter struct apply { }; // list, such as  }; 

    où j’ai testé des trucs dans le compilateur de code d’exécution à l’ adresse : http://fr.cppreference.com/w/cpp/language/parameter_pack mais aussi des modèles Ellipses et Variadic dans visual studio 2013: .com / fr-fr / library / dn439779.aspx