在回答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::vector
和std::deque
(表100),但这不是意味着存在移动赋值运算符:可以定义复制赋值运算符,而不定义移动赋值运算符,此类将为MoveAssignable
。
为了以防万一,我检查了GCC和Clang,如果没有移动赋值运算符,std::vector::erase()
确实调用了复制赋值运算符,std::deque::erase()
执行相同的操作(DEMO)。< / p>
所以问题是:我错过了什么,或者这是标准中的(编辑)问题?
更新 我已提交了LWG issue #2477。
答案 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
的措辞也将是
澄清了一点。