J'ai ce code:

#include <iostream>
#include <vector>

template<typename T>
void print_size(std::vector<T> a)
{
    std::cout << a.size() << '\n';
}

int main()
{
    std::vector<int> v {1, 2, 3};
    print_size(v);

    auto w = {1, 2, 3};
    // print_size(w); // error: no matching function for call to 'print_size'
                      // candidate template ignored: could not match 'vector' against 'initializer_list'
}

... qui compile et s'exécute sans aucun problème. Mais si j'active la ligne commentée, cela produit l'erreur no matching function for call to 'print_size'.

Je voudrais savoir quelle est la bonne façon d'écrire ce code en C ++ 11 et versions ultérieures.

2
Lone Learner 23 mai 2018 à 17:34

4 réponses

Meilleure réponse

Pour auto w = {1, 2, 3};, le type de w sera std::initializer_list<int>, et print_size(w); échoue car le paramètre de modèle T ne peut pas être déduit; la déduction d'argument de modèle ne prend pas en compte les conversions implicites.

La déduction de type ne prend pas en compte les conversions implicites (autres que les ajustements de type répertoriés ci-dessus): c'est le travail de résolution de surcharge, qui se produit plus tard.

Vous pouvez spécifier explicitement l'argument du modèle,

print_size<int>(w);

Ou vous pouvez faire de w un std::vector<int> à la place; et si vous persistez à utiliser auto, vous devez spécifier le type explicitement.

auto w = std::vector<int>{1, 2, 3};
print_size(w);
5
songyuanyao 23 mai 2018 à 16:42

Le problème est le type d'argument de print_size. Votre auto w = {1, 2, 3}; est de type std::initializer_list<int> et cela ne correspond pas à un vector<T>, il n'y a pas de conversion automatique.

Vous pouvez donc corriger print_size de cette façon:

template<class T>
void print_size(std::initializer_list<T> a)
{
    std::cout << a.size() << '\n';
}

Ou mieux encore, changez la façon dont le modèle est paramétré:

template<class T>
void print_size(const T& a)
{
    std::cout << a.size() << '\n';
}
2
Marek R 23 mai 2018 à 14:50

Sans les guides de déduction C ++ 17, le compilateur ne peut malheureusement pas déduire T pour le paramètre std::vector<T> d'un argument de type std::initializer_list<T>.

Je suggérerais d'ajouter une surcharge pour print_size(std::initializer_list<T> const&).

1
Maxim Egorushkin 23 mai 2018 à 14:43

Casting w serait une solution

    print_size((std::vector<int>)w);
0
erkut 23 mai 2018 à 14:42