Я хочу реализовать синглтоноподобную функциональность, используя std :: call_once просто для удовольствия или, возможно, мог бы улучшить сам шаблон Singleton. Вот что я пробовал до сих пор, но я застрял. Любая помощь будет высоко оценена.
class single {
public:
private:
single(){}
friend void boo(unique_ptr<single>&);
};
void boo(unique_ptr<single>& f) {
f.reset(new single());
}
unique_ptr<single>& bar() {
static once_flag flag;
static unique_ptr<single> f;
call_once(flag, boo,f);
return f;
}int main()
{
unique_ptr<single> f;
f = move(bar());
unique_ptr<single> f2;
f2 = move(bar()); // this should not work but it does, work-around?
}
static
достаточно. Это делает потокобезопасную инициализацию для вас, нет необходимости call_once
:
Если несколько потоков пытаются инициализировать одну и ту же статическую локальную переменную одновременно, инициализация происходит ровно один раз (аналогичное поведение может быть получено для произвольных функций с
std::call_once
).Примечание: в обычных реализациях этой функции используются варианты шаблона блокировки с двойной проверкой, который уменьшает накладные расходы времени выполнения для уже инициализированной локальной статики до одного неатомарного логического сравнения.
Следовательно:
unique_ptr<single>& bar() {
static unique_ptr<single> f{new single};
return f;
}
Или лучше:
single& bar() {
static single f;
return f;
}
Других решений пока нет …