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

时间:2015-02-02 12:40:05

标签: c++ language-lawyer c++14

在回答another question的过程中,我偶然发现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 1}}被称为等于被擦除元素后向量中元素数量的次数。

     

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

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

还需要T MoveAssignable erase()同时使用std::vectorstd::deque(表100),但这不是意味着存在移动赋值运算符:可以定义复制赋值运算符,而不定义移动赋值运算符,此类将为MoveAssignable

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

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

更新 我已提交了LWG issue #2477

1 个答案:

答案 0 :(得分:9)

Lenexa在提出问题时遇到问题got Immediate status

  

这个措辞与N4296有关。

     

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

     

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

     

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

     

-4- 复杂性T的析构函数被称为等于被删除元素数的次数,但是 move 赋值运算符T的{​​{1}}被称为等于被擦除元素后向量中元素数量的次数。

也就是说,如果决议被接受,则不会特别提及std::vector::erase的移动分配,std::deque::erase的措辞也将是 澄清了一点。