Когда заменить глобальный std:: unique_ptr на singleton

Сотрудник настаивал на использовании Meyer Singleton для всех глобальных переменных указателя, поскольку "нет гарантии, что построение глобального unique_ptr не будет выбрасывать". Поэтому вместо:

#include <memory>

std::unique_ptr<Foo> ptr(nullptr); // Apparently this isn't safe.

int main(/*blah*/)
{
    ptr.reset(new Foo());
}

Теперь имеем

unique_ptr<Foo> singleton
{ 
    try 
    { 
        static unique_ptr<Foo> ptr(); 
        return ptr; 
    } 
    catch (...) 
    { 
        std::cerr << "Failed to create single instance\n"; 
        exit(1); 
    } 
    return unique_ptr<Type>(); 
}

int main()
{
}

Для меня это похоже на решение проблемы. У него есть точка?

Ответ 1

Ваш коллега неверен (или, может быть, просто устарел, пред-стандартные версии unique_ptr могут отличаться). Конструктор nullptr_t unique_ptr гарантированно не бросает (20.7.1.2):

constexpr unique_ptr (nullptr_t) noexcept : unique_ptr() {}

Так как он также constexpr (и поскольку nullptr является константным выражением), его необходимо инициализировать во время постоянной инициализации (3.6.2/2). Таким образом, управление порядком инициализации (другая причина, по которой может быть полезна однопользовательская система Meyers) также не применяется.

Ответ 2

"нет гарантии, что построение глобального unique_ptr не будет выбрасывать"

И если он бросает, что происходит? Приложение прекращается, хотя в стандарте не указывается, если стек разматывается, если вы не поймаете исключение (в качестве глобальной переменной нет места для исключения исключения). Я не совсем понимаю, как предлагаемое решение является явным улучшением.