在std :: vector :: erase()和std :: deque :: erase()中复制/移动分配


135

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

这就是C ++ 14关于std::deque::erase[deque.modifiers]/4-6,重点是我的)的看法:

效果: ...

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

抛出:除非的复制构造函数,move构造函数,赋值运算符或move赋值运算符抛出异常,否则什么都不会发生T

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

效果: ...

复杂性:的析构函数的T调用次数等于擦除的元素数,但是的移动分配运算符T调用次数等于在擦除的元素之后向量中的元素数。

抛出:除非的复制构造函数,move构造函数,赋值运算符或move赋值运算符抛出异常,否则什么都不会发生T

如您所见,它们的异常规范是相同的,但是std::vector明确提到了调用移动赋值运算符。

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

为了以防万一,我检查了GCC和Clang,并确实std::vector::erase()在没有移动分配运算符的情况下调用了复制分配运算符,并且std::deque::erase()执行了同样的操作(DEMO)。

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

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


14
似乎是标准中的缺陷。
巴里

4
^ ack。LWG问题将是适当的。
哥伦布2015年

4
通常,标准草案足够好。这是您应该看真实事物的情况之一。
Mark Ransom

3
@MarkRansom std :: dequestd :: vector的当前标准来源与问题中的相同,因此最终版本不同的可能性很小。
安东·萨文

3
N4141的措词与N4140相同。
布赖恩

Answers:


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一些澄清。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.