Реализация синглтоноподобной функциональности с использованием std :: call_once - PullRequest
0 голосов
/ 21 сентября 2018

Я хочу реализовать синглтоноподобную функциональность, используя 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?
}

1 Ответ

0 голосов
/ 21 сентября 2018

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...