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 ?
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>& 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>& 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&, 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>& 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>& 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!