- 如果移动构造函数是
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;
... ...
标记行中给出的评论实际上是错误的-对于那些可以在移动构造时抛出异常的仅可移动类型,可能会失败的不可逆变异实际上已经在我们将旧元素移动到它们的新位置时开始了。
简单地看,我认为一个抛出异常的仅可移动类型否则不能放入向量中,但也许不应该这样做?
insert
),有一个专门针对move-only类型的特殊段落:“如果非CopyInsertable
类型的T的移动构造函数引发异常,则效果未指定。” 此外,请注意noexcept(false)
不能保证函数不抛出异常。 - dyp