1
votes

Spécialisation de modèle C ++ avec tout paramètre non-type

Je souhaite spécialiser un modèle. La spécialisation prend comme type un autre modèle, qui a un paramètre de modèle non type. Je veux que la spécialisation s'applique à toute valeur du paramètre non-type. Je peux me spécialiser pour une valeur non-type spécifique, mais je ne sais pas comment le faire en général.

Par exemple:

template<typename T, int N>   // first definition
struct A;

template<typename T>          // second definition
struct B;

template<>                    // this compiles, N is fixed
struct B<A<float,1>>;

template<>              // For general N this doesn't compile, says
struct B<A<float,int>>;  // "expected a constant of type ‘int’, got ‘int’"

Y a-t-il un moyen de l'accomplir, de sorte que j'ai une spécialisation de B si le paramètre est A, quelle que soit la valeur de int N pour A?


1 commentaires

J'ai écrit une réponse. Si vous l'avez trouvé utile, pensez à le voter / l'accepter! ( stackoverflow.com/help/someone-answers )


3 Réponses :


1
votes

Au lieu de

B<A<float, 1>> b1;     // Uses the specialization
B<A<float, 200>> b2;   // Also uses the specialization

utilisez

template<int N> 
struct B<A<float, N>>;

Le premier ne fonctionne pas car A nécessite un type et un int , pas deux types.

Je souhaite que la spécialisation s'applique à toute valeur du paramètre non-type.

Ma suggestion le fera effectivement.

template<> 
struct B<A<float,int>>; 


0 commentaires

2
votes

La raison pour laquelle cela ne fonctionne pas est que vous passez le type int comme paramètre de modèle, où vous avez besoin d'une valeur entière. Pour autoriser n'importe quelle valeur entière comme paramètre, vous devez écrire quelque chose comme

template<int P> // For any int value P
struct B<A<float,P>>;


0 commentaires

0
votes

Spécialisation comme:

B<A<float, size_t(666)> > possessed_object;

N'est pas correct puisque la déclaration template struct A; indique que N est le template non-type / paramètre non-template de type int pour le modèle de classe. Et il ne peut pas être remplacé par un type (dans ce cas int ).

Dans ce cas, on devrait fournir exclusivement un paramètre de valeur à la place et comme on souhaite avoir la spécialisation pour n'importe quelle valeur mais un seul type ( float dans les exemples suivants), d'abord une représentation de la valeur sous forme de cas générique doit apparaître dans le template <___> afin de pouvoir ensuite être utilisée pour définir le terme B <_____> .

il y a 2 options dans ce cas comme:

template<typename T, size_t N> 
struct A{...};
template<auto N>
struct B<A<float,N>>{...};

Ou comme:

B<A<float, 666> > possessed_object;

Dans les deux cas, le compilateur se prépare à rechercher une valeur à substituer à N comme paramètre de modèle non-type / non-modèle.

Enfin, le modèle de classe B peut être utilisé comme:

template<auto N>
struct B<A<float,N>>{...};

Veuillez également noter que si le type de N était différent de int , par exemple s'il était de size_t , lors de l'utilisation de la deuxième option (celle avec auto ) comme:

template<int N>
struct B<A<float,N>>{...};

alors l'utilisation (assurée) devient comme:

template<>
struct B<A<float,int>>{...};

Bien que dans certaines implémentations cela puisse ne pas avoir d'importance et la première utilisation mentionnée peut encore être utilisé.

Bonne chance!