Maison >développement back-end >C++ >Quand la dégradation du pointeur remplace-t-elle la déduction du modèle dans la résolution de surcharge C ?

Quand la dégradation du pointeur remplace-t-elle la déduction du modèle dans la résolution de surcharge C ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-29 18:50:11313parcourir

When Does Pointer Decay Override Template Deduction in C   Overload Resolution?

Ambiguïté dans la résolution de surcharge : décroissance du pointeur par rapport à la déduction de modèle

En C, lorsque des fonctions surchargées sont disponibles, déterminer laquelle appeler peut être ambigu. Un de ces cas implique que la dégradation du pointeur ait priorité sur un modèle déduit.

Racine de l'ambiguïté

Considérons une fonction qui imprime la longueur d'une chaîne :

template <size_t N>
void foo(const char (&s)[N]) {
    std::cout << "array, size=" << N - 1 << std::endl;
}

foo("hello") // prints array, size=5

Pour prendre en charge les non-tableaux, une surcharge supplémentaire est ajouté :

void foo(const char* s) {
    std::cout << "raw, size=" << strlen(s) << std::endl;
}

De façon inattendue, la première surcharge n'est plus appelée :

foo("hello") // now prints raw, size=5

Dégradation du pointeur vs déduction de modèle

L'ambiguïté se produit parce qu’un tableau est essentiellement un pointeur vers son premier élément. La dégradation du pointeur convertit automatiquement un tableau en pointeur lorsqu'il le passe en argument. Cependant, la déduction du modèle entraînerait une correspondance exacte avec la première surcharge.

Selon le standard C, la résolution de surcharge donne la priorité aux fonctions qui ne sont pas des spécialisations d'un modèle de fonction (sauf dans certains cas). Dans ce cas, la conversion tableau en pointeur est une transformation Lvalue avec une priorité inférieure à la déduction de modèle.

Briser l'ambiguïté

Une façon de résoudre l'ambiguïté est pour définir également la deuxième surcharge comme modèle de fonction, permettant un classement partiel :

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;
}

En spécifiant la contrainte de type, le Le compilateur peut en déduire que la première surcharge doit être utilisée pour les tableaux, tandis que la seconde surcharge gère les non-tableaux.

En résumé, même si le déclin du pointeur offre un raccourci pour accéder au premier élément d'un tableau, cela peut conduire à ambiguïté inattendue dans la résolution de surcharge lorsque des modèles sont impliqués. Un examen attentif des surcharges de fonctions et une utilisation réfléchie des contraintes de type sont essentiels pour éviter de tels pièges.

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