在 std::vector::erase() 和 std::d eque::erase() 中复制/移动赋值
Copy/move assignment in std::vector::erase() and std::deque::erase()
在回答另一个问题的过程中,我偶然发现了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
,明确提到调用移动分配运算符。
还需要MoveAssignable
T
,以便erase()
同时使用 std::vector
和 std::deque
(表 100),但这并不意味着存在移动分配运算符:可以定义复制赋值运算符,而不定义移动赋值运算符,此类将被MoveAssignable
。
以防万一,我检查了 GCC 和 Clang,如果没有移动分配运算符,确实std::vector::erase()
调用复制分配运算符,std::deque::erase()
也这样做 (DEMO)。
所以问题是:我错过了什么,还是这是标准中的(编辑)问题?
更新:我已经提交了 LWG 问题 #2477。
在Lenexa会议上,该问题获得了建议解决方案的即时状态:
此措辞与 N4296 有关。
将 23.3.3.4 [deque.modifiers]/5 更改为:
-5- 复杂性:对
T
析构函数的调用次数与擦除的元素数相同,但对T
赋值运算符的调用次数不超过被擦除元素之前的元素数和被擦除元素之后的元素数中的较小者。将 23.3.6.5 [矢量修饰符]/4 更改为:
-4- 复杂性:
T
的析构函数称为等于擦除元素数的次数,但T
的移动赋值运算符称为等于擦除元素后向量中元素数的次数。
也就是说,如果决议被接受,则不会特别提及std::vector::erase
的移动分配,并且std::deque::erase
的措辞将是澄清了一下。
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- std::multimap::erase() 在迭代时
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么"std::set::erase(const key_type&)"返回"size_type"而不是"bool"?
- std::vector::erase() 真的会在擦除时使迭代器失效吗?
- 为什么 std::set::erase 与 std::set::insert 不一致?
- 新的 std::map::erase() 签名 C++17.
- 如何为向量实现 std::erase ?
- C++代码"x.erase(std::remove(x.begin(), x.end(), ), x.end())"是如何工作的?
- std::vector::erase 的 MoveAssignable 要求与 std::vector::emplace_back 的 MoveInsertable 要求
- 没有 std::string .erase() 的重载函数实例
- 使用std::vector中的函数erase
- 为什么 std::vector 迭代器在 erase() 调用后失效?
- std :: vector :: erase(item)需要为项目定义的分配操作员
- 使用 std::unique 和 vector.erase 删除除最后一次出现的重复元素之外的所有元素
- std::map::erase()-重载速度更快
- std::string::erase() 的定义行为是什么,带有 string::npos
- Lint更喜欢在std:string上使用erase()方法,而不是clear()方法
- 为什么std::whatever::erase()是一个方法,std::remove()是独立函数
- std::erase 和 std::remove 组合以删除特定元素不适用于特定示例