Вместо этого отправил код:
Foo& GetFoo()
{
static std::once_flag fooInitFlag;
static Foo f;
std::call_once(fooInitFlag, [&Foo]()
{
Foo.Init();
});
return std::ref(f);
}
сделать это:
struct Initialized_foo
{
Foo item;
Initialized_foo() { item.Init(); }
};
auto get_foo()
-> Foo&
{
static Initialized_foo the_foo;
return the_foo.item;
}
Это не более безопасно, но это проще, и, следовательно, более безопасным в отношении непреднамеренно введенных ошибок.
Обратите внимание, что стандарт гарантирует единственную инициализацию здесь, даже в контексте многопоточности.
лучше, в идеале каждый Foo
insteance должен быть надлежащим образом инициализируется Foo
конструктора, а не с помощью метода Init
. Но это не всегда возможно.
Вам не нужно 'once_flag' вещь. Единая инициализация гарантирована. Использовать конструктор, а не метод 'Init' - –
Да. Обратите внимание, что вам все еще нужно, что в msvc 2013, но не в компиляторе C++ 11, где статическая инициализация является потокобезопасной. (не возвращайте std :: ref (f), просто f) –
Здесь вам не нужно 'std :: ref'; просто верните 'f'. И это безопасно, так как 'f' останется. –