ark1974
ark1974

Reputation: 655

Realize a singleton-like functionality using std::call_once

I want to realize a singleton-like functionality using std::call_once just for fun or perhaps could improve on the Singleton Pattern itself. Here's what I tried so far but I am stuck. Any help will be highly appreciated.

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?
}

Upvotes: 0

Views: 311

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136425

static is enough. It does thread-safe initialization for you, no need for call_once:

If multiple threads attempt to initialize the same static local variable concurrently, the initialization occurs exactly once (similar behavior can be obtained for arbitrary functions with std::call_once).

Note: usual implementations of this feature use variants of the double-checked locking pattern, which reduces runtime overhead for already-initialized local statics to a single non-atomic boolean comparison.

Hence:

unique_ptr<single>& bar() {
    static unique_ptr<single> f{new single};
    return f;
}

Or better:

single& bar() {
    static single f;
    return f;
}

Upvotes: 2

Related Questions