Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do std::make_shared and std::make_unique have a "nothrow" version?

For the new operator, we have the std::nothrow version:

std::unique_ptr<T> p = new(std::nothrow) T();

Do we have something like this for the std::make_shared or std::make_unique?

like image 373
jack sparow Avatar asked Jul 18 '19 10:07

jack sparow


People also ask

Why use make_ unique and make_ shared?

It is recommended to use the 'make_unique/make_shared' function to create smart pointers. The analyzer recommends that you create a smart pointer by calling the 'make_unique' / 'make_shared' function rather than by calling a constructor accepting a raw pointer to the resource as a parameter.

Does make_unique throw?

A little late, but make_unique can itself throw according to cppreference: make_unique "may throw std::bad_alloc or any exception thrown by the constructor of T.

What does std:: make_ unique do?

make_unique prevents the unspecified-evaluation-order leak triggered by expressions like foo(unique_ptr<X>(new X), unique_ptr<Y>(new Y)) . (Following the advice "never say new " is simpler than "never say new , unless you immediately give it to a named unique_ptr ".)

When was make_unique introduced?

The std::make_unique function was introduced in the C++14 standard. Make sure to compile with the -std=c++14 flag to be able to use this function. The object gets destroyed once p goes out of scope.


1 Answers

No, we don't. Looking through the cppreference pages for make_unique and make_shared, we see that every version uses the default new overload.

It is not difficult to implement one, though, something like this:

template <class T, class... Args>
std::unique_ptr<T> make_unique_nothrow(Args&&... args)
    noexcept(noexcept(T(std::forward<Args>(args)...)))
{
    return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}

template <class T, class... Args>
std::shared_ptr<T> make_shared_nothrow(Args&&... args)
    noexcept(noexcept(T(std::forward<Args>(args)...)))
{
    return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}

(Note that this version of make_shared_nothrow does not avoid double allocation as make_shared does.) C++20 added many new overloads for make_unique, but they can be implemented in a similar way. Also, per comment,

Don't forget to check the pointer before using it, when using this version. — Superlokkus Jul 18 '19 at 10:46

like image 147
L. F. Avatar answered Oct 21 '22 10:10

L. F.