【问题标题】:Copy/move assignment in std::vector::erase() and std::deque::erase()在 std::vector::erase() 和 std::deque::erase() 中复制/移动赋值
【发布时间】: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::vectorstd::deque 一起使用(表 100),但这并不意味着存在移动赋值运算符:一可以定义复制赋值操作符,不定义移动赋值操作符,该类为MoveAssignable

为了以防万一,我检查了 GCC 和 Clang,如果没有移动赋值运算符,std::vector::erase() 确实会调用复制赋值运算符,std::deque::erase() 也会这样做 (DEMO)。

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

更新: 我已经提交了LWG issue #2477

【问题讨论】:

  • 似乎是标准中的一个缺陷。
  • ^ 确认。一个 LWG 问题将是合适的。
  • 通常标准草案已经足够好了。这是您应该查看真实事物的情况之一。
  • @MarkRansom std::dequestd::vector 的标准的当前来源与问题中的相同,因此最终版本不同的可能性很小。
  • N4141 的措辞与 N4140 相同。

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


【解决方案1】:

在 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赋值运算符987654325@被调用的次数等于向量中删除元素后的元素个数。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-24
    • 2015-01-04
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多