Maison >développement back-end >C++ >Pourquoi la déduction de type échoue-t-elle avec std :: function et les fonctions Lambda en C 11 ?

Pourquoi la déduction de type échoue-t-elle avec std :: function et les fonctions Lambda en C 11 ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-20 05:50:10327parcourir

Why Does Type Deduction Fail with std::function and Lambda Functions in C  11?

Déduction de type avec std::function et fonctions Lambda en C 11

Lorsque vous travaillez avec des modèles en C 11, la déduction de type peut être un fonctionnalité puissante. Cependant, il existe certains scénarios dans lesquels la déduction de type échoue, en particulier lorsque des fonctions std::function ou lambda sont impliquées.

Dans l'exemple suivant, le test de fonction accepte un ensemble de type A et renvoie le même ensemble sans explicitement en spécifiant le type de modèle :

template<class A>
set<A> test(const set<A>&amp; input) {
    return input;
}

L'appel de cette fonction avec test(mySet) ailleurs dans le code fonctionne comme prévu. Cependant, lors de l'utilisation d'une fonction avec une fonction lambda, la déduction de type échoue :

template<class A>
set<A> filter(const set<A>&amp; input,function<bool(A)> compare) {
    // ... implementation
}

Essayer d'appeler filter avec filter(mySet,[](int i) { return i%2==0; }) ; entraîne l'erreur :

error: no matching function for call to ‘filter(std::set&amp;, main()::)’

Ce problème se pose car les lambdas ne sont pas des fonctions ou des objets std::function. Ce sont des objets fonctions dotés de propriétés spécifiques définies par la norme. La déduction de type ne fonctionne qu'avec des types exacts et les lambdas ne répondent pas à ce critère.

Pour résoudre ce problème, vous pouvez convertir le lambda en std::function ou fournir explicitement le type de modèle :

// Convert lambda to std::function
std::function<bool(int)> func = [](int i) { return i%2 ==0; };
set<int> myNewSet = filter(mySet,func);

// Provide template type explicitly
set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });

Alternativement, vous pouvez redéfinir la fonction pour accepter un paramètre de modèle pour la CompareFunction :

template<class A,class CompareFunction>
set<A> filter(const set<A>&amp; input,CompareFunction compare) {
    // ... implementation
}

Avec cette modification, vous pouvez appeler la fonction sans spécifier le type de modèle :

set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });

La déduction de type peut également être problématique avec les lambdas multi-arguments. Dans de tels cas, utiliser auto peut être une solution utile :

template<class Value,class CompareType,class IndexType>
auto filter(const set<Value>&amp; input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> {
    // ... implementation
}

Cette fonction peut être appelée comme suit :

map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });

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