在回答另一个问题的过程中,我偶然发现< code > STD::vector::erase()和< code>std::deque::erase()的措辞略有不同。
这是C 14对std::deque::erase
([deqe.modifiers]/4-6
,强调我的)所说的:
影响:。。。
复杂度:调用析构函数的次数与擦除的元素数相同,但调用赋值操作符的次数不超过擦除元素之前的元素数和擦除元素之后的元素数中较少者。
抛出:除非T
的复制构造函数、移动构造函数、赋值操作符或移动赋值操作符抛出异常,否则无异常。
下面是它对std::向量::erase
([vector.modifiers]/3-5
)的描述:
影响:。。。
复杂度:T
的析构函数称为等于被擦除元素个数的次数,但T
的移动赋值操作符称为等于被擦除元素后向量中元素个数的次数。
抛出:除非T
的复制构造函数、移动构造函数、赋值操作符或移动赋值操作符抛出异常,否则无异常。
正如您所看到的,两者的异常规范是相同的,但是对于< code>std::vector,明确提到了调用移动赋值操作符。
还要求< code>T为< code>MoveAssignable,以便< code>erase()与< code>std::vector和< code > STD::dequee (表100)一起工作,但这并不意味着存在移动赋值运算符:可以定义复制赋值运算符,而不定义移动赋值运算符,此类将为< code>MoveAssignable。
为了以防万一,我用GCC和Clang检查了一下,如果没有移动赋值操作符,那么< code > STD::vector::erase()确实会调用复制赋值操作符,而< code>std::deque::erase()也是这样做的(演示)。
所以问题是:我错过了什么,还是这是标准中的(编辑)问题?
更新:我已经提交了LWG问题#2477。
在Lenexa会议上,该问题立即获得了拟议解决方案的状态:
此措辞与 N4296 有关。
将23.3.3.4[deque . modifiers]/5改为:
-5-复杂度:对T
的析构函数的调用次数与被擦除的元素数相同,但对T
的赋值操作符的调用次数不超过被擦除元素前的元素数和被擦除元素后的元素数中较少者。
将23.3.6.5[vector . modifiers]/4改为:
-4- 复杂性:T 的析构函数称为等于被擦除元素数的次数,但
T
的移动赋值运算符称为等于被擦除元素后向量中元素数的次数。
也就是说,如果决议被接受,则不会特别提及 std::vector::erase
的移动分配,并且 std::d eque::erase
的措辞也会得到一点澄清。