Maison >développement back-end >C++ >Pourquoi est-ce que j'obtiens des erreurs de redéfinition lors de l'utilisation de std::enable_if_t dans les arguments du modèle ?

Pourquoi est-ce que j'obtiens des erreurs de redéfinition lors de l'utilisation de std::enable_if_t dans les arguments du modèle ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-27 02:23:14977parcourir

Why do I get redefinition errors when using std::enable_if_t in template arguments?

Erreurs de redéfinition anormales avec std::enable_if_t dans les arguments du modèle

En C, std::enable_if est une métafonction qui permet l'activation conditionnelle d'un modèle en fonction de certaines contraintes. Il a récemment été remplacé par std::enable_if_t, plus concis. Cependant, lorsqu'ils tentent de porter du code existant pour utiliser la nouvelle syntaxe, certains utilisateurs rencontrent des erreurs de redéfinition inattendues.

Exemple de code

Considérez le code suivant écrit en utilisant std : Enable_if :

template<typename T,
         typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr>
void f() { }

template<typename T,
         typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr>
void f() { }

Ce code est compilé avec succès, avec des spécialisations distinctes pour int et double. Maintenant, supposons que nous voulions réécrire ceci en utilisant la syntaxe std::enable_if_t :

template<typename T,
         typename = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }

template<typename T,
         typename = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }

Erreur inattendue

Contrairement aux attentes, ce code mis à jour ne parvient pas à se compiler, avec GCC 5.2 reporting :

error: redefinition of 'template<class T, class> void g()'
       void g() { }

Explication

L'erreur réside dans le fait que std::enable_if_t représente un type, pas une condition. Lorsqu'il est utilisé comme argument de modèle, il spécifie une contrainte de type. Dans le cas std::enable_if d'origine, le deuxième paramètre de modèle est un type de pointeur, alors que dans la version std::enable_if_t, il devient un alias de type. Il en résulte deux arguments de modèle différents avec le même type (void()).

Solution

Pour éviter cette ambiguïté, nous devons nous assurer que le deuxième paramètre du modèle représente une contrainte de type unique. Une façon d'y parvenir consiste à utiliser un paramètre de modèle factice :

template<typename T,
         typename U = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }

template<typename T,
         typename U = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }

Dans ce cas, U est un paramètre factice qui sert uniquement à différencier les deux arguments du modèle. Avec cette modification, le code sera compilé avec succès.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn