I\'m a bit confused about the purpose of std::call_once
. To be clear, I understand exactly what std::call_once
does, and how to use it. It\'
One thing that call_once
does for you is handle exceptions. That is, if the first thread into it throws an exception inside of the functor (and propagates it out), call_once
will not consider the call_once
satisfied. A subsequent invocation is allowed to enter the functor again in an effort to complete it without an exception.
In your example, the exceptional case is also handled properly. However it is easy to imagine a more complicated functor where the exceptional case would not be properly handled.
All this being said, I note that call_once
is redundant with function-local-statics. E.g.:
CSingleton& CSingleton::GetInstance()
{
static std::unique_ptr m_instance(new CSingleton);
return *m_instance;
}
Or more simply:
CSingleton& CSingleton::GetInstance()
{
static CSingleton m_instance;
return m_instance;
}
The above is equivalent to your example with call_once
, and imho, simpler. Oh, except the order of destruction is very subtly different between this and your example. In both cases m_instance
is destroyed in reverse order of construction. But the order of construction is different. In your m_instance
is constructed relative to other objects with file-local scope in the same translation unit. Using function-local-statics, m_instance
is constructed the first time GetInstance
is executed.
That difference may or may not be important to your application. Generally I prefer the function-local-static solution as it is "lazy". I.e. if the application never calls GetInstance()
then m_instance
is never constructed. And there is no period during application launch when a lot of statics are trying to be constructed at once. You pay for the construction only when actually used.