Основной вопрос
Я пытаюсь скомпилировать следующий код с GCC 4.7.2:
#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;
}
И кажется, что это не так, потому что вывод следующий:
$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
Итак, мой первый вопрос:
Является ли это отказом GCC, или код не является законным С++ 11? Это исправлено в любой последней версии GCC?
Использование трюка в shared_ptr factory
Я рассматриваю возможность создания артефакта, основанного на этом принципе, но использующего нелитеральную статическую переменную. Этот артефакт предназначен для factory shared_ptr <T> , которые избегают создания новых объектов T, когда вам нужен только дублированный контейнер shared_ptr для одного и того же экземпляра.
Этот артефакт будет выглядеть так:
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;
}
Насколько я знаю, если проблема GCC, обсуждавшаяся ранее, не является проблемой с точки зрения соответствия С++ 11, этот артефакт тоже не должен быть проблемой. Единственное, что нужно сделать, используя этот хак, - не устанавливать результирующий shared_ptr <T> объект для любого глобального объекта, который может быть разрушен после статической переменной.
Я прав?