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!