std :: make_shared和std :: make_unique是否具有“ nothrow”版本?

jac*_*row 7 c++ new-operator c++-standard-library nothrow

对于新操作员,我们具有以下std::nothrow版本:

std::unique_ptr<T> p = new(std::nothrow) T();
Run Code Online (Sandbox Code Playgroud)

我们对于std::make_shared或有这样的东西std::make_unique吗?

L. *_* F. 8

不,我们不。翻翻cppreference页make_uniquemake_shared,我们可以看到,每一个版本使用默认的new过载。

但是,实现这样的实现并不难:

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)...));
}
Run Code Online (Sandbox Code Playgroud)

(请注意,此版本的版本make_shared_nothrow并不能避免重复分配make_shared。)C ++ 20为添加了许多新的重载make_unique,但是可以通过类似的方式实现它们。另外,根据评论

使用此版本时,请不要忘记在使用之前检查指针。-Superlokkus 19 年  7月18日在10:46

  • 使用此版本时,请不要忘记在使用之前检查指针。 (2认同)
  • “*我们看到每个版本都使用默认的 new 重载。*” `allocate_shared` 使用提供的分配器,而不是 `new`。另外,如果用户想要使用“nothrow”“new”,这可能意味着他们不想打开异常处理周期。 (2认同)