Les expressions Lambda sont implémentées en créant une classe avec un opérateur d'appel de fonction surchargé et en référençant les variables en tant que membres. Cela suggère que la taille des expressions lambda varie en fonction du nombre de variables référencées. Cependant, std::function doit avoir une taille fixe. Comprendre l'implémentation de std::function est crucial.
Effacement de type pour les foncteurs de taille variable
std::function utilise une technique appelée effacement de type pour gérer les foncteurs de tailles variables. Prenons un exemple simplifié de std::function qui encapsule un pointeur de fonction vers int(double):
struct callable_base { virtual int operator()(double d) = 0; virtual ~callable_base() {} }; template <typename F> struct callable : callable_base { F functor; callable(F functor) : functor(functor) {} virtual int operator()(double d) { return functor(d); } }; class function_int_double { std::unique_ptr<callable_base> c; public: template <typename F> function(F f) { c.reset(new callable<F>(f)); } int operator()(double d) { return c(d); } };
Dans cet exemple, std::function stocke un unique_ptr vers le type polymorphe callable_base. Pour différents foncteurs, de nouveaux types dérivés de callable_base sont créés et instanciés dynamiquement. L'objet std::function conserve une taille cohérente tout en acceptant des foncteurs de différentes tailles dans le tas.
Répartition et optimisation dynamiques
Pour améliorer les performances, implémentations dans le monde réel de std::function optimise la répartition dynamique et tire parti des optimisations de petits objets. Cependant, le concept sous-jacent reste le même.
Comportement des copies std::function
Les copies de std::function sont accompagnées de copies de l'objet appelable qu'elles encapsulent . Ceci est confirmé par le test suivant :
int main() { int value = 5; typedef std::function<void()> fun; fun f1 = [=]() mutable { std::cout << value++ << '\n' }; fun f2 = f1; f1(); fun f3 = f1; f2(); f3(); }
La sortie демонстрирует (5, 5, 6), indiquant que des copies de l'objet fonction sont effectuées, plutôt que de partager l'état.
Cette compréhension de l'implémentation de std::function garantit son utilisation efficace avec des foncteurs de différentes tailles.
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!