【发布时间】:2015-04-01 09:55:16
【问题描述】:
在回答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)。
所以问题是:我是否遗漏了什么,或者这是标准中的(编辑)问题?
更新: 我已经提交了LWG issue #2477。
【问题讨论】:
-
似乎是标准中的一个缺陷。
-
^ 确认。一个 LWG 问题将是合适的。
-
通常标准草案已经足够好了。这是您应该查看真实事物的情况之一。
-
@MarkRansom std::deque 和 std::vector 的标准的当前来源与问题中的相同,因此最终版本不同的可能性很小。
-
N4141 的措辞与 N4140 相同。
标签: c++ language-lawyer c++14