Certaines sources sur les internets (spécifiquement Celui-ci ) dit que STD :: Fonction utilise de petites optimisations de fermeture, par exemple Il n'allocoue pas le tas si la taille de la fermeture est inférieure à une certaine quantité de données (le lien ci-dessus indique 16 octets pour GCC)
donc je suis allé creuser via g ++ en-têtes p>
semble si une telle optimisation est appliquée ou non est décidé par ce bloc de code dans l'en-tête "fonctionnel" (g ++ 4.6.3) p> et certaines lignes vers le bas: p> EG Si _Local_storage () est vrai_type, que le placement nouveau-nouveau est appelé, sinon, neuf régulière p> La définition de _Local_storage est le suivi: p> max stored locally size: 16, align: 8
lambda size: 1
lambda align: 1
stored locally: false
3 Réponses :
STD :: L'attribution de la fonction est un détail de mise en œuvre; Enfin, j'ai vérifié que 12 octets est la taille du fonctionnement maximal de MSVC, 16 pour GCC, 24 pour Boost + MSVC. p>
ADZM: Oui, cela est mentionné dans le lien au début de la question. Cependant, je ne vois pas que c'est en fait le cas avec g ++
Je parie si vous avez ajouté ceci: vous recevrez: p> au moins c'est ce que Ideone dit . p> p>
Oui, c'est à peu près implique de mon test. Question est: c'est final? Dr. Dobbs a tort et nous avons toujours des allocations de tas?
@Alexi., Cela dépend vraiment du compilateur.
AS de GCC 4.8.1, la Fonction STD :: Fonction de LibstDC ++ Optimise uniquement les pointeurs aux fonctions et aux méthodes. Donc, quelle que soit la taille de votre foncteur (Lambdas incluse), l'initialisation d'une STD :: fonction de celui-ci déclenche une allocation de tas. Malheureusement, il n'y a pas de support pour les allocateurs personnalisés non plus.
Visual C ++ 2012 et LLVM LIBC ++ permettent d'attribuer l'allocation pour tout fonceur suffisamment petit. P>
Remarque, pour cette optimisation de votre ampleur de votre ameublement devrait remplir STD :: is_nothrow_move_constructible. Ceci est pour supporter noexcept std :: Fonction :: Swap (). Heureusement, Lambdas satisfait à cette exigence si toutes les valeurs capturées font. P>
Vous pouvez écrire un programme simple pour vérifier le comportement sur divers compilateurs: P>
#include <functional> #include <iostream> // noexpect missing in MSVC11 #ifdef _MSC_VER # define NOEXCEPT #else # define NOEXCEPT noexcept #endif struct A { A() { } A(const A&) { } A(A&& other) NOEXCEPT { std::cout << "A(A&&)\n"; } void operator()() const { std::cout << "A()\n"; } char data[FUNCTOR_SIZE]; }; int main() { std::function<void ()> f((A())); f(); // prints "A(A&&)" if small functor optimization employed auto f2 = std::move(f); return 0; }
Je confirme vos résultats de ce programme: ideone.com/kzae6u Vous pouvez vérifier sur Clang ( melpon.org/wandbox ) que le même programme n'attribuait que la mémoire de mémoire pour une très grande capture ...