首页 文章

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

提问于
浏览
136

在回答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 ,明确提到了调用移动赋值运算符 .

还需要 TMoveAssignable erase()std::vectorstd::deque (表100)一起使用,但这并不意味着存在移动赋值运算符:可以定义复制赋值运算符,而不是定义移动赋值运算符,这个类将是 MoveAssignable .

为了以防万一,我检查了GCC和Clang,如果没有移动赋值运算符, std::vector::erase() 实际上调用了复制赋值运算符,并且 std::deque::erase() 执行相同的操作(DEMO) .

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

Update: 我已经提交了LWG issue #2477 .

1 回答

  • 9

    在Lenexa Session 上提出了议案got Immediate status

    这个措辞与N4296有关 . 将23.3.3.4 [deque.modifiers] / 5更改为:-5-复杂性:对T的析构函数的调用次数与擦除的元素数相同,但对T的赋值运算符的调用次数为no超过擦除元素之前的元素数量和擦除元素之后的元素数量中的较小者 . 将23.3.6.5 [vector.modifiers] / 4更改为:-4-复杂性:T的析构函数被称为等于被擦除元素数的次数,但T的移动赋值运算符被称为次数等于擦除元素后向量中元素的数量 .

    也就是说,如果决议被接受,则不会特别提及 std::vector::erase 的移动分配,并且 std::deque::erase 的措辞也会稍微澄清一下 .

相关问题