Question principale
Je tente de compiler le code suivant avec GCC 4.7.2:
#include
int foo() {
static int bar;
return [&bar] () { return bar++; } (); // lambda qui capture par référence
}
int main (int argc, char* argv[]) {
std::cout << foo() << std::endl;
return 0;
}
Et il semble que ça ne se passe pas bien, car le résultat est le suivant:
$p2.cpp: Lors de la fonction ‘int foo()’:
$p2.cpp:6:14: avertissement: capture de la variable ‘bar’ avec une durée de vie non automatique [activé par défaut]
$p2.cpp:4:16: remarque: ‘int bar’ déclaré ici
Donc, ma première question serait:
S'agit-il d'un échec de GCC, ou le code n'est-il pas légitime en C++11? Est-ce corrigé dans une version récente de GCC?
Utiliser l'astuce dans une fabrique de shared_ptr
J'envisage de construire un artefact basé sur ce principe mais en utilisant une variable statique non littérale. Cet artefact est censé être une fabrique d'objets shared_ptr< T >, qui évite la création de nouveaux objets T lorsque vous avez simplement besoin d'un conteneur shared_ptr en double pour la même instance.
Cet artefact ressemblerait à ceci:
std::shared_ptr create(std::string name) {
static std::unordered_map> registry;
if (auto it = registry.find(name) != registry.end())
return registry[name].lock();
auto b = std::shared_ptr(
new Foo(name),
[®istry] (Foo* p) {
registry.erase(p->getName());
delete p;
});
registry.emplace(name,b);
return b;
}
D'après ce que je sais, si le problème GCC discuté précédemment ne pose pas de problème en termes de conformité C++11, cet artefact ne devrait pas non plus poser de problème. La seule chose à prendre en compte en utilisant cette astuce est de ne pas définir l'objet shared_ptr< T > résultant sur un objet global qui pourrait être détruit après la variable statique.
Suis-je dans le vrai à ce sujet?