La dégradation du pointeur a priorité sur la déduction du modèle
Lors de l'écriture de code qui fonctionne sur des chaînes, il est courant de rencontrer un dilemme où tenter de surcharger une fonction permettant de prendre en charge les représentations de chaînes basées sur un tableau et non basées sur un tableau peut entraîner un comportement inattendu.
Dans ce cas spécifique scénario, une fonction initiale foo est définie pour imprimer la longueur d'un tableau de caractères :
template <size_t N> void foo(const char (&s)[N]) { std::cout << "array, size=" << N-1 << std::endl; }
Cette fonction accepte des tableaux de caractères et affiche la longueur du tableau. Cependant, lors de l'extension de foo pour gérer également les chaînes non-tableaux, une ambiguïté surgit :
void foo(const char* s) { std::cout << "raw, size=" << strlen(s) << std::endl; }
L'intention est que la deuxième surcharge foo gère les chaînes non-tableaux chaînes, mais étonnamment, cette extension conduit à contourner la surcharge d'origine pour les tableaux et les non-tableaux strings :
foo("hello") // prints raw, size=5
Ce comportement inattendu découle du concept de désintégration du pointeur. Les tableaux sont essentiellement des pointeurs vers leur premier élément, et la conversion d'un tableau en pointeur est une opération très peu coûteuse. En conséquence, le compilateur donne la priorité à la surcharge qui accepte un paramètre de pointeur, même si elle nécessite une conversion implicite de l'argument tableau.
Pour garantir le comportement souhaité, lorsque la surcharge basée sur le tableau est utilisée pour les tableaux, il est nécessaire d'introduire une surcharge supplémentaire :
template <typename T> auto foo(T s) -> std::enable_if_t<std::is_convertible<T, char const*>{}> { std::cout << "raw, size=" << std::strlen(s) << std::endl; }
Cette surcharge utilise la déduction de modèle et restreint son applicabilité aux types pouvant être convertis en pointeurs de caractères. Grâce à un classement partiel, le compilateur sélectionne désormais correctement la fonction foo appropriée en fonction du type d'argument.
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!