c – 异常安全移动物体离开堆叠
我正在编写一个带有以下函数的互斥保护堆栈,用于从可能失败的顶部弹出一个值:
bool try_pop(T& value) { std::lock_guard<std::mutex> lock(mutex_); if (ctr_.empty()) return false; value = std::move(ctr_.back()); ctr_.pop_back(); return true; } 我正在使用std :: vector作为底层容器.为了在堆栈中存储一个不可复制的T(例如std :: unique_ptr),我使用了std :: move从传感器的背面取下T,否则就会产生一个副本.两个问题:a)这是正确的吗? T会被移动还是被复制? b)我担心异常安全.如果移动抛出,则不会弹出堆栈,但最高值可能处于半移动状态.这是可能的,我该如何解决? 解决方法
a)假设它有一个移动构造函数,它将被移动.对于已定义复制构造函数但未定义移动构造函数的类型,将复制它.
b)如果你需要强异常保证,那么你应该使用std :: move_if_noexcept,它只在输入提供noexcept()移动构造函数时启用移动.这样,如果移动构造函数可以抛出,它将诉诸于复制,因此如果抛出异常,则对象在堆栈上保持不变.明确提供了std :: move_if_noexcept,以帮助在这种情况下提供强有力的保证. 编辑:正如Howard Hinnant指出的那样,当前的代码示例是使用移动赋值,而不是移动构造,因此std :: move_if_noexcept不太可能做你想要的.要在使用赋值时解决它,您需要编写自己的包装器,它基于std :: move_if_noexcept: template <class T> typename std::conditional< !std::is_nothrow_move_assignable<T>::value && std::is_copy_assignable<T>::value,const T&,T&&>::type move_if_assign_noexcept(T& x) noexcept { return std::move(x); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |