在std :: vector :: erase()和std :: deque :: erase()中复制/移动赋值

在回答另一个问题的过程中,我偶然发现了std::vector::erase()std::deque::erase()略有不同的措辞。

这是C ++ 14关于std::deque::erase[deque.modifiers]/4-6 ,强调我的) [deque.modifiers]/4-6

效果:

复杂性:对析构函数的调用次数与删除元素的数量相同,但对赋值运算符的调用次数不超过元素数量中的较小值。在删除元素之前以及元素数量擦除元素。

抛出:除非复制构造函数,移动构造函数,赋值运算符或移动T赋值运算符引发exception,否则为Nothing。

这是什么说std::vector::erase[vector.modifiers]/3-5 ):

效果:

复杂性: T的析构函数被称为等于被擦除元素数量的次数,但T移动赋值运算符被称为等于被擦除元素之后的向量中元素数量的次数。

抛出:除非复制构造函数,移动构造函数,赋值运算符或移动T赋值运算符引发exception,否则为Nothing。

正如你所看到的,它们的exception规范都是相同的,但是对于std::vector ,明确提到移动赋值运算符被调用。

还有要求TMoveAssignableerase()std::vectorstd::deque (表100)一起工作,但这并不意味着存在移动赋值操作符:可以定义一个拷贝分配运算符,而不定义移动赋值运算符,而这个类将是MoveAssignable

为了以防万一,我用GCC和Clang进行了检查,如果没有移动赋值操作符, std::deque::erase()也是一样的( DEMO ),那么std::vector::erase()调用复制赋值操作符。

所以问题是:我错过了什么,或者这是标准的(编辑)问题?

更新:我已经提交了一个LWG问题#2477 。

在莱内克萨会议上,这个问题得到了立即提出的决议的地位 :

这个措辞是相对于N4296。

将23.3.3.4 [deque.modifiers] / 5更改为:

复杂性T的析构函数的调用次数与删除元素的数量相同,但T的赋值操作符调用次数不超过删除元素之前的元素数量中的较小者和擦除元素之后的元素的数量。

将23.3.6.5 [vector.modifiers] / 4更改为:

-4- 复杂度T的析构函数被称为等于被擦除元素数量的次数,但T移动赋值运算符被称为次数,该次数等于擦除元素之后的向量中元素的数量。

也就是说,如果分辨率被接受, std::vector::erase的移动赋值就没有特别的提及了,而std::deque::erase的措辞也会有所澄清。