C++ 在std::vector::erase()和std::deque::erase()中复制/移动赋值

C++ 在std::vector::erase()和std::deque::erase()中复制/移动赋值,c++,language-lawyer,c++14,C++,Language Lawyer,C++14,在回答的过程中,我偶然发现std::vector::erase()和std::deque::erase() 这是C++14关于std::deque::erase([deque.modifiers]/4-6,强调我的): 效果: 复杂性:调用析构函数的次数与删除的元素数相同,但是 调用赋值运算符的次数不超过元素数中的较小者 被擦除元素之前和被擦除元素之后的元素数 抛出:除非T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符抛出异常,否则不会抛出任何内容 下面是关于std::vector::

在回答的过程中,我偶然发现
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
,明确提到调用了move赋值操作符

还有一个要求是
T
MoveAssignable
erase()
同时使用
std::vector
std::deque
(表100),但这并不意味着存在移动分配操作符:可以定义复制分配操作符,而不定义移动分配操作符,并且该类将是
可移动可分配的

为了以防万一,我使用GCC和Clang进行了检查,实际上,
std::vector::erase()
在没有移动赋值操作符的情况下调用了复制赋值操作符,
std::deque::erase()
也会这样做()

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

更新:
我在Lenexa会议上提交了一份.

报告,提出了解决方案:

此措辞与N4296相关

将23.3.3.4[deque.修饰符]/5更改为:

-5-复杂性:调用
T
的析构函数的次数与删除的元素数相同,但是对
T
的赋值运算符的调用次数不超过被擦除元素之前的元素数和被擦除元素之后的元素数中的较小者

将23.3.6.5[向量修饰符]/4更改为:

-4-复杂性:
T
的析构函数被称为等于被擦除元素数的次数,而
T
的移动赋值运算符被称为等于被擦除元素后向量中元素数的次数

也就是说,如果接受解决方案,则不会特别提及
std::vector::erase
的移动分配,并且
std::deque::erase
的措辞也将被删除
有点澄清。

似乎是标准中的缺陷。^ack。LWG问题是合适的。通常,标准草案已经足够好了。这是您应该查看真实内容的情况之一。@Markransem和的标准的当前来源与问题中的相同,因此最终版本差异的可能性很小。N4141与N4140的措辞相同。