Quand j'définir cette fonction,
template<class A>
set<A> test(const set<A>& input) {
return input;
}
Je peux l'appeler à l'aide de test(mySet)
ailleurs dans le code, sans avoir à définir explicitement le type de modèle. Cependant, lorsque j'utilise la fonction suivante:
template<class A>
set<A> filter(const set<A>& input,function<bool(A)> compare) {
set<A> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret.insert(*it);
}
}
return ret;
}
Lorsque j'appelle cette fonction à l'aide d' filter(mySet,[](int i) { return i%2==0; });
J'obtiens l'erreur suivante:
error: no matching function for call to ‘filter(std::set<int>&, main()::<lambda(int)>)'
Cependant, toutes ces versions n' travail:
std::function<bool(int)> func = [](int i) { return i%2 ==0; };
set<int> myNewSet = filter(mySet,func);
set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });
set<int> myNewSet = filter(mySet,function<bool(int)>([](int i){return i%2==0;}));
Pourquoi le c++11 est impossible de deviner le type de modèle quand j'ai mis la fonction lambda directement à l'intérieur de l'expression sans créer directement un std::function
?
EDIT:
Par les conseils de Luc Danton dans les commentaires, ici, est une alternative à la fonction que j'avais précédemment qui n'a pas besoin de modèles pour être transmis de manière explicite.
template<class A,class CompareFunction>
set<A> filter(const set<A>& input,CompareFunction compare) {
set<A> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret.insert(*it);
}
}
return ret;
}
Cela peut être appelé par set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
sans avoir besoin du modèle.
Le compilateur peut même deviner les types de retour, dans une certaine mesure, à l'aide de la nouvelle decltype mot-clé et à l'aide de la nouvelle fonction de type de retour de la syntaxe. Voici un exemple qui convertit un ensemble à une carte, à l'aide d'une fonction de filtrage et une fonction qui génère les clés sur la base des valeurs:
template<class Value,class CompareType,class IndexType>
auto filter(const set<Value>& input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> {
map<decltype(index(*(input.begin()))),Value> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret[index(*it)] = *it;
}
}
return ret;
}
Il peut aussi être appelé sans l'aide du modèle directement, comme
map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });