domanda principale
Sto cercando di compilare il seguente codice con GCC 4.7.2:catturare una variabile statica per riferimento in C++ 11 lambda
#include <iostream>
int foo() {
static int bar;
return [&bar]() { return bar++; }(); // lambda capturing by reference
}
int main (int argc, char* argv[]) {
std::cout << foo() << std::endl;
return 0;
}
E sembra che non sia andando bene, come l'uscita è questa:
$p2.cpp: In function ‘int foo()’:
$p2.cpp:6:14: warning: capture of variable ‘bar’ with non-automatic storage duration [enabled by default]
$p2.cpp:4:16: note: ‘int bar’ declared here
Quindi, la mia prima domanda sarebbe:
Si tratta di un errore di GCC o il codice non è legittimo in C++ 11? È corretto in qualsiasi versione recente di GCC?
Utilizzando il trucco in una fabbrica shared_ptr
considero di costruire un manufatto in base a questo principio, ma utilizzando una variabile statica non letterale. Questo artefatto è pensato per essere una fabbrica di oggetti shared_ptr < T, che evitano la creazione di nuovi oggetti T quando è sufficiente un contenitore shared_ptr duplicato per la stessa istanza.
Questo artefatto sarà simile:
std::shared_ptr<Foo> create(std::string name) {
static std::unordered_map<std::string,std::weak_ptr<Foo>> registry;
if (auto it = registry.find(name) != registry.end())
return registry[name].lock();
auto b = std::shared_ptr<Foo>(
new Foo(name),
[®istry] (Foo* p) {
registry.erase(p->getName());
delete p;
});
registry.emplace(name,b);
return b;
}
Per quanto ne so, se il problema GCC discusso in precedenza non è un problema in termini di C++ 11 conformità, questo manufatto non dovrebbe essere un problema o. L'unica cosa da fare attenzione usando questo hack, è di non impostare l'oggetto T_previsto risultante < a qualsiasi oggetto globale che potrebbe essere distrutto dopo la variabile statica.
Ho ragione su questo?
Compila e gira bene su g ++ 4.6.3 – goji