noexcept
或者没有复制构造函数(仅移动类型) 我发现这个相当令人惊讶,因为只有移动类型的投掷移动器仍会有使用move_if_noexcept
的代码调用此移动器。
是否已经给出了彻底的理由? (可能直接或在N2983之间?)
不编码会不会更好,而不是仍然不得不面对不可恢复的移动场景? N2983中给出的vector
示例很不错:
void reserve(size_type n)
{
... ...
new ((void*)(new_begin + i)) value_type( std::move_if_noexcept( (*this)[i]) ) );
}
catch(...)
{
while (i > 0) // clean up new elements
(new_begin + --i)->~value_type();
this->deallocate( new_begin ); // release storage
throw;
}
*!* // -------- irreversible mutation starts here -----------
this->deallocate( this->begin_ );
this->begin_ = new_begin;
... ...
标记行中给出的注释实际上是错误的 - 对于可以投掷移动构造的仅移动类型,当我们将旧元素移动到新位置时,实际上已经开始了 - 可能失败 - 不可逆转的突变。
简单地看一下,我会说投掷移动的类型不能放入矢量中,否则它可能不应该?
答案 0 :(得分:6)
简单地看一下,我会说投掷移动类型不能 否则会被放入矢量中,但也许它不应该?
我相信你已经很好地总结了委员会对于仅移动 - 禁止(假) - 类型的容器的选择。
一个。委员会绝对认为他们无法默默地将现有的C ++ 03代码从具有强大的异常安全性转变为具有基本的异常安全性。
B中。对于那些具有强大异常安全性的函数,委员会更倾向于让这些成员继续具有强大的异常安全性,即使对于无法编写的代码(例如,用于操作仅移动类型的函数)。
委员会意识到它可以完成上述两个目标,但B)中的情况除外,在移动施工期间,只移动类型可能会抛出。这些案例仅限于vector
IIRC的一些成员职能:push_back
,reserve
。请注意,vector
的其他成员已经只提供基本的异常安全性(即使在C ++ 98/03中),例如:赋值,插入(除非在末尾插入),擦除。
考虑到所有这一切,委员会的决定应该是客户创建一个vector
只移动 - 禁止(错误)类型,客户放松强者会更有用基本的异常安全(就像其他向量成员一样),而不是拒绝编译。
这只是客户端为C ++ 11编写的新代码,而不是遗留代码,因为在C ++ 11之前不存在仅移动类型。毫无疑问,C ++ 11的教育工作者应该鼓励他们的学生编写noexcept(真正的)移动成员。但是,具有基本异常安全保证的代码不是那么危险,也不是不寻常的,因此应该禁止它。毕竟,std :: lib已经充满了只带有基本异常安全保证的代码。