8 votes

Tester si deux modèles sont identiques, même avec des paquets de paramètres non typés en tant que paramètres

Donc, je dois trouver si deux modèles sont identiques, même si les paramètres ne le sont pas, c'est-à-dire si dans T et U T et U sont les mêmes, même si A et B ne le sont pas. std::is_same ne peut pas être utilisé, car il ne concerne que le type complet.

**

Ma première solution était la suivante:

template
struct is_same_template : std::false_type {};

template typename T, typename A, typename B>
struct is_same_template, T> : std::true_type {};

template typename T, typename A, template typename U, typename B>
struct is_same_template, U> : std::false_type {};

Cela fonctionne, mais seulement pour les modèles avec un paramètre, donc je l'ai étendu à:

template
struct is_same_template : std::false_type {};

template typename T, typename... A, typename... B>
struct is_same_template, T> : std::true_type {};

template typename T, typename... A, template typename U, typename... B>
struct is_same_template, U> : std::false_type {};

Cela fonctionne très bien, même pour les modèles avec des paquets de paramètres.
Exemple:

template 
struct Test1 {};

template 
struct Test2 {};

struct Foo {};
struct Bar {};

int main(int argc, char** argv) {    
    std::cout << std::boolalpha;
    std::cout << is_same_template, Test2>::value << '\n';
    std::cout << is_same_template, Test2>::value << '\n';
    std::cout << is_same_template, Test2>::value << '\n';

    std::cout << is_same_template, Test1>::value << '\n';
    std::cout << is_same_template, Test1>::value << '\n';
    std::cout << is_same_template, Test1>::value << '\n';

    return 0;
}

Résultat:

false
false
false
true
true
true

Mon problème est que dans le cas d'utilisation réel pour lequel j'ai fait cela, le paramètre de modèle est un paquet de paramètres int:

template 
struct ArgIndexes {};

Je ne savais pas que les types et les non-types sont gérés différemment. Lors des tests avec ArgIndexes, le résultat était toujours la valeur de

template
struct is_same_template : std::false_type {};

Y a-t-il un moyen de le faire fonctionner à la fois avec des paquets de paramètres de type et de non-type sans gérer chaque type de paquet de paramètres de non-type spécifiquement?

EDIT

Je viens de réaliser que

template typename T, typename... A, template typename U, typename... B>
struct is_same_template, U> : std::false_type {};

est redondant et peut être supprimé.


2voto

Sebastian.M Points 242

Ainsi fonctionne l'auto. Tous mes tests ont fonctionné avec cette combinaison :

template
struct is_same_template : std::false_type {};

template typename T, typename... A, typename... B>
struct is_same_template, T> : std::true_type {};

template typename T, auto... A, auto... B>
struct is_same_template, T> : std::true_type {};

Je n'avais pas testé l'auto auparavant car le Clang intégré dans mon IDE me disait que l'auto n'était pas autorisé. Eh bien si, et ça fonctionne. Merci @Jarod42 de m'avoir fait reconsidérer cela.

1voto

Caleth Points 17517

Si vous souhaitez uniquement vérifier les modèles avec un seul jeu de paramètres de valeur, vous pouvez ajouter cette spécialisation :

template typename T, A... X, A... Y>
struct is_same_template, T> : std::true_type {};

Utilisé comme ceci :

template 
struct Test1 {};

template 
struct Test2 {};

int main(int argc, char** argv) {    
    std::cout << std::boolalpha;
    std::cout << is_same_template, Test2<1, 2, 3>>::value << '\n';
    std::cout << is_same_template, Test2<2>>::value << '\n';
    std::cout << is_same_template, Test2<2>>::value << '\n';

    std::cout << is_same_template, Test1<1>>::value << '\n';
    std::cout << is_same_template, Test1<2>>::value << '\n';
    std::cout << is_same_template, Test1<2>>::value << '\n';

    return 0;
}

En direct sur Wandbox

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X