异常安全移动运算符

Ath*_*ase 3 c++ move

我通常(尝试)使用复制交换习语编写异常安全的复制赋值运算符,我想知道在编写移动赋值运算符时是否应该关注异常。下面是一个复制赋值运算符的例子:

template<class T>
CLArray<T>&
CLArray<T>::operator=( const CLArray& rhs )
{
    CLArray tmp( rhs );
    std::swap( size_, tmp.size_ );
    std::swap( data_, tmp.data_ );
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

但是移动分配呢?我的意思是,如果在此移动操作期间在代码中的其他地方抛出异常,我将丢失两个对象的状态,对吗?所以我必须先创建一个本地副本,然后删除除新创建的之外的所有内容CLArray......

template <class T>
CLArray<T>&
CLArray<T>::operator=( CLArray<T>&& rhs )
{
    size_ = rhs.size_;
    data_ = std::move( rhs.data_ );
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这data_是一个 std::vector,感谢您的回答!

Mik*_*our 5

实际上,如果移动构造函数可能抛出异常,则提供异常保证可能很困难或不可能。

我建议像标准库那样做:如果移动构造T没有抛出,则记录某些操作只有异常保证(或者,在某些情况下,只允许)。通过复制对象来确保保证会破坏所有类型的移动赋值的好处,而不仅仅是可能抛出的(非常罕见的)类型。