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

Ant*_*vin 135 c++ language-lawyer c++14

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

这就是C++ 14所说的std::deque::erase([deque.modifiers]/4-6强调我的):

效果: ......

复杂性:对析构函数的调用次数与擦除的元素数相同,但对赋值运算符的调用次数不超过删除元素之前的元素数量和次要元素数量之后的次数.擦除元素.

抛出:除非复制构造函数,移动构造函数,赋值运算符或移动赋值运算符抛出异常,否则无效T.

以下是关于std::vector::erase([vector.modifiers]/3-5)的内容:

效果: ......

复杂性:的析构函数T被调用的次数等于擦除的元件的数量的数量,但该移动赋值运算符T被称为的次数等于在向量元素的擦除元件后的数目的数目.

抛出:除非复制构造函数,移动构造函数,赋值运算符或移动赋值运算符抛出异常,否则无效T.

正如您所看到的,两者的异常规范是相同的,但是为了std::vector明确提到它,调用了移动赋值运算符.

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

为了以防万一,我检查了GCC和Clang,std::vector::erase()如果没有移动赋值运算符,确实调用了复制赋值运算符,并且std::deque::erase()执行相同的操作(DEMO).

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

更新: 我已经提交了LWG问题#2477.

Ant*_*vin 9

在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::deque::erase稍后会澄清措辞.