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
Susan Sarandonoriginal
2024-12-05 01:52:09193parcourir

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

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

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

On peut même écrire ceci :

const auto il = {'a', 'b', 'c'};
printme(il);

Ou :

printme<std::initializer_list<char>>({'a', 'b', 'c'});

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'})

Ou :

printme<std::initializer_list<char>>({'a', 'b', 'c'})

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.

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>.

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