Je lisais des fermetures sur le net. Je me demandais si C++ avait une fonction intégrée pour les fermetures ou s'il y avait un moyen de mettre en œuvre des fermetures en C++?
La dernière norme C++, C++ 11 , a des fermetures.
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
Si vous comprenez la fermeture comme une référence à une fonction qui a un contexte incorporé, persistant, caché et indissociable (mémoire, état), alors oui:
class add_offset {
private:
int offset;
public:
add_offset(int _offset) : offset(_offset) {}
int operator () (int x) { return x + offset; }
}
// make a closure
add_offset my_add_3_closure(3);
// use cloure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;
le suivant modifie son état:
class summer
{
private:
int sum;
public:
summer() : sum(0) {}
int operator () (int x) { return sum += x; }
}
// make a closure
summer adder;
// use closure
adder(3);
adder(4);
std::cout << adder(0) << std::endl;
L'état intérieur ne peut pas être référencé (accessible) de l'extérieur.
Selon la façon dont vous le définissez, une fermeture peut contenir une référence à plusieurs fonctions ou, deux fermetures peuvent partager le même contexte, c'est-à-dire que deux fonctions peuvent partager le même état persistant, ...,.
La fermeture signifie ne pas contenir de variables libres - elle est comparable à une classe avec uniquement des attributs privés et uniquement des méthodes publiques.
Oui, cela montre comment vous pouvez implémenter une fonction avec un état sans utiliser de foncteur.
#include <iostream>
#include <functional>
std::function<int()> make_my_closure(int x){
return [x]() mutable {
++x;
return x;
};
}
int main()
{
auto my_f = make_my_closure(10);
std::cout << my_f() << std::endl; // 11
std::cout << my_f() << std::endl; // 12
std::cout << my_f() << std::endl; // 13
auto my_f1 = make_my_closure(1);
std::cout << my_f1() << std::endl; // 2
std::cout << my_f1() << std::endl; // 3
std::cout << my_f1() << std::endl; // 4
std::cout << my_f() << std::endl; // 14
}
J'ai oublié le mot-clé mutable qui a introduit un comportement indéfini (la version clang renvoyait une valeur poubelle). Telle que mise en œuvre, la fermeture fonctionne bien (sur GCC et clang)
Oui, C++ 11 a des fermetures nommées lambdas .
En C++ 03, il n'y a pas de support intégré pour les lambdas, mais il y a l'implémentation Boost.Lambda .
Je soupçonne que cela dépend de ce que vous entendez par fermeture. Le sens que j'ai toujours utilisé implique un ramasse-miettes (bien que je pense qu'il pourrait être implémenté en utilisant le comptage de références); contrairement aux lambdas dans d'autres langages, qui capturent les références et maintiennent l'objet référencé vivant, les lambdas C++ capturent une valeur, ou l'objet référencé est pas maintenu vivant (et la référence peut facilement pendre).