在回答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的移动赋值运算符被称为等于向量中元素数量的次数 . 被擦除的元素 . 抛出:除非复制构造函数,移动构造函数,赋值运算符或T的移动赋值运算符抛出异常,否则无效 .
正如您所看到的,两者的异常规范是相同的,但对于 std::vector
,明确提到了调用移动赋值运算符 .
还需要 T
为 MoveAssignable
erase()
与 std::vector
和 std::deque
(表100)一起使用,但这并不意味着存在移动赋值运算符:可以定义复制赋值运算符,而不是定义移动赋值运算符,这个类将是 MoveAssignable
.
为了以防万一,我检查了GCC和Clang,如果没有移动赋值运算符, std::vector::erase()
实际上调用了复制赋值运算符,并且 std::deque::erase()
执行相同的操作(DEMO) .
所以问题是:我错过了什么,或者这是标准中的(编辑)问题?
Update: 我已经提交了LWG issue #2477 .
1 回答
在Lenexa Session 上提出了议案got Immediate status:
也就是说,如果决议被接受,则不会特别提及
std::vector::erase
的移动分配,并且std::deque::erase
的措辞也会稍微澄清一下 .