Maison > développement back-end > C++ > Pourquoi la déduction de type de modèle échoue-t-elle avec `initializer_list` en C ?

Pourquoi la déduction de type de modèle échoue-t-elle avec `initializer_list` en C ?

Susan Sarandon
Libérer: 2024-12-05 01:52:09
original
193 Les gens l'ont consulté

Why Does Template Type Deduction Fail with `initializer_list` in C  ?

initializer_list et déduction de type de modèle

La déduction de type de modèle est une fonctionnalité puissante de C qui permet au compilateur de déduire les arguments de type d'un modèle à partir des arguments transmis au modèle. Cependant, dans certains cas, le compilateur est incapable de déduire les arguments de type et le modèle doit être explicitement instancié avec les arguments de type souhaités.

Considérez la fonction suivante :

template<typename T>
void printme(T&& t) {
  for (auto i : t)
    std::cout << i;
}
Copier après la connexion

Ceci La fonction attend un seul paramètre avec un type activé pour commencer()/end(). La question est, pourquoi le code suivant est-il illégal ?

printme({'a', 'b', 'c'});
Copier après la connexion

Quand tous ces éléments sont légitimes :

printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});
Copier après la connexion

On peut même écrire ceci :

const auto il = {'a', 'b', 'c'};
printme(il);
Copier après la connexion

Ou :

printme<std::initializer_list<char>>({'a', 'b', 'c'});
Copier après la connexion

La première ligne de code est illégale car l'argument du modèle T n'a pas pu être déduit. Si l'argument du modèle est explicitement spécifié, cela fonctionnera, par exemple :

printme<std::vector<char>>({'a', 'b', 'c'})
Copier après la connexion

Ou :

printme<std::initializer_list<char>>({'a', 'b', 'c'})
Copier après la connexion

Les autres lignes de code sont légales car l'argument a un type bien défini , donc l'argument du modèle T peut être très bien déduit.

La partie qui peut prêter à confusion est que l'auto choisira le type std::initializer_list mais l'argument modèle ne le sera pas. En effet, le § 14.8.2.5/5 de la norme C 11 indique explicitement qu'il s'agit d'un contexte non déduit pour un argument de modèle :

A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have std::initializer_list or reference to possibly cv-qualified std::initializer_list type.
Copier après la connexion

Cependant, avec auto, le § 7.1.6.4/6 a prise en charge explicite de std::initializer_list<>:

if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>.
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal