Насколько я понимаю, С++ 14 ввел std::make_unique
потому что из-за того, что не был указан порядок оценки параметров, это было небезопасно:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
(Объяснение: если оценка сначала выделяет память для необработанного указателя, затем вызывает g()
и перед конструкцией std::unique_ptr
генерируется исключение, то память просачивается.)
Вызов std::make_unique
был способом ограничения порядка вызовов, таким образом делая вещи безопасными:
f(std::make_unique<MyClass>(param), g()); // Syntax B
С тех пор, С++ 17 разъяснили порядок оценки, что делает Синтаксис безопасными тоже, так что здесь мой вопрос: есть ли еще причина использовать std::make_unique
над std::unique_ptr
конструктора в С++ 17? Можете привести несколько примеров?
На данный момент единственная причина, которую я могу себе представить, заключается в том, что он позволяет набирать MyClass
только один раз (при условии, что вам не нужно полагаться на полиморфизм с помощью std::unique_ptr<Base>(new Derived(param))
). Однако это кажется довольно слабой причиной, особенно когда std::make_unique
не позволяет указывать удалитель, в то время как конструктор std::unique_ptr
делает.
И, чтобы быть ясным, я не сторонник удаления std::make_unique
из стандартной библиотеки (сохраняя это имеет смысл по крайней мере для обратной совместимости), а скорее задаюсь вопросом, существуют ли еще ситуации, в которых настоятельно рекомендуется std::unique_ptr