c++ - std::unique_ptr<T>::reset 的强异常保证

标签 c++ c++11

假设我有一个函数reset:

template<typename T, typename... Args>
void reset(unique_ptr<T>& p, Args&&... args)
{
    // implementation (1)
    p.reset(new T(forward<Args>(args)...));

    // implementation (2)
    p = make_unique<T>(forward<Args>(args)...);
}

我是否正确:

  1. 对于实现(1),如果在销毁p的原pointee时抛出异常,将泄漏new内存;

  2. 实现(2),什么都不能泄露;

  3. 所以我们应该更喜欢 (2) 而不是 (1)。

最佳答案

作为 Jonathan Wakely points out ,这一点没有实际意义,因为如果析构函数无论如何都会抛出,则 unique_ptr::reset 的行为是未定义的。

如果析构函数抛出,两个版本都有 UB,所以这不是偏爱其中一个的理由。

[unique.ptr.single.modifiers] (标准草案)

3 Requires: The expression get_deleter()(get()) shall be well formed, shall have well-defined behavior, and shall not throw exceptions.


即使行为定义明确...

(1) 不会泄漏。 unique_ptr 在销毁旧参数之前取得参数的所有权。

4 Effects: Assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not equal to nullptr, calls get_deleter()(old_p). [ Note: The order of these operations is significant because the call to get_deleter() may destroy *this. — end note ]


偏爱其中一个的原因

  • (1) 仅需要 C++11,(2) 需要 C++14 或您自己的 make_unique 样板。
  • (2) 没有对 new 的显式调用,因此使用旧的经验法则更容易推断内存整洁度:“每个 new 一个 delete”。

关于c++ - std::unique_ptr<T>::reset 的强异常保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38447426/

相关文章:

c++ - 如何将异步与不返回任何内容的 lambda 一起使用?

c++ - QByteArray 的标准替代品

c++ - decltype 规则定义左值或纯右值

c++ - 为什么抓取窗口标题的代码会导致应用程序崩溃?

c++ - 我使用 C++ 标准库的 find 有什么问题?

c++ - 如何使用 GetTokenInformation() 恢复权限? C++

c++ - 那么为什么 i =++i + 1 在 C++11 中定义良好?

C++0x lambda + boost::function 问题

c++ - 在 QTextEdit 中放置图像的几种方法

c++ - 从另一个 std::thread 调用 Qt 对象方法