Pourquoi ce modèle variadique imbriqué est-il un argument invalide?
Si je définis un struct
template Bar
qui accepte un argument template:
template <template <int,bool,char> class>
struct Bar {};
je peux instancier à l'aide d'un struct
modèle Zod
:
template <int,bool,char> struct Zod {};
Bar<Zod> a;
je peux aussi l'instancier à l'aide d'un imbriquée struct
modèle JKL
:
struct GHI {
template <int,bool,char>
struct JKL {};
};
Bar <GHI::JKL> b;
Pourquoi je ne peux pas instancier Bar
en utilisant un variadique imbriqué struct
modèle <!--12?:
template <typename ...Ts>
struct ABC {
template <Ts ...>
struct DEF {};
};
Bar<ABC<int,bool,char>::DEF> c;
G++ 4.9.2 se plaint d'une inadéquation de type / valeur; tandis que Clang 3.4.2 l'erreur signale que l'argument template template a des paramètres de template différents de ceux du paramètre template template correspondant.
2 réponses
donnons au paquet de paramètres de DEF un nom pour faciliter la consultation:
template <typename ...Ts>
struct ABC {
template <Ts ... Values>
struct DEF {};
};
Le point clé ici est que par [temp.param] / p15,Ts... Values
un pack d'extension de Ts
et une déclaration d'un paramètre pack Values
.
Si template-parameter [...]paramètre-déclaration que déclare un paquet de paramètres (8.3.5), puis le template-parameter est un paquet de paramètres du modèle (14.5.3). Un paquet de paramètres de template qui est un paramètre-déclaration dont le type contient un ou plusieurs paquets de paramètres NON étendus est une extension de paquet.
Depuis DEF
prend un paquet de paramètre non-type, il ne correspond pas à un paramètre template qui ne prend pas les packs ([temp.arg.modèle]/p3):
modèle-argument correspond à un modèle template-parameter P quand chaque modèle paramètres dans l' template-parameter-listemodèle-argument’s correspondant de la classe de modèle ou alias modèle correspond au modèle correspondant paramètre dans le modèle-paramètres-liste de P. Deux paramètres du modèle correspondent s'ils sont du même type (type, non-type, template), pour non-type template-parameter s, leurs types sont équivalents (14.5.6.1), et pour le modèle template-parameters, chacun de leur correspondant template-parameters correspond, de manière récursive. Quand P est template-parameter-liste contient un template parameter pack (14.5.3), le template parameter pack correspondra à zéro ou plus template paramètres ou paquets de paramètres de modèle dans le template-parameter-liste de A avec le même type et la même forme que le paramètre template pack en P (ignorant si ces template paramètres paramètre de modèle pack.)
Pour être sûr, Values
est plutôt bizarre pour les packs - pour chaque spécialisation de ABC
,Values
doit contenir un nombre fixe d'arguments - mais avec les règles actuelles c'est toujours un pack, donc les règles pour les packs s'appliquent.
comme Barry l'a déjà dit à propos de:
ABC<int,bool,char>::DEF<4,true,'c'> foo
Et faire un essai et a travaillé sur Coliru en ligne compilateur gcc 5.1 c++14 dans ce site Compilateur:
#include <iostream>
template <template <int,bool,char> class>
struct Bar {};
template <int,bool,char> struct Zod {};
Bar<Zod> a;
struct GHI {
template <int,bool,char>
struct JKL {};
};
Bar <GHI::JKL> b;
template <template <typename... Ts> class>
struct Base {};
template<typename... Ts>
struct Floor {};
Base<Floor> c;
template <typename... Ts>
struct ABC {
template <Ts... val>
struct DEF {};
};
ABC<int,bool,char>::DEF<4,true,'c'> foo;
j'ai fait une recherche et j'ai trouvé cette liste de paramètres de Template.
l'extension du paquet peut apparaître dans la liste des paramètres du modèle:
template<typename... T> struct value_holder
{
template<T... Values> // expands to a non-type template parameter
struct apply { }; // list, such as <int, char, int(&)[5]>
};
où j'ai testé quelques trucs dans le compilateur run code à: http://en.cppreference.com/w/cpp/language/parameter_pack mais aussi j' trouvé ces Ellipses et les gabarits de Variadic dans visual studio 2013: https://msdn.microsoft.com/en-us/library/dn439779.aspx