Copy/move assignment in std::vector::erase() and std::deque::erase()

C++Language LawyerC++14

C++ Problem Overview


In the process of answering another question I stumbled upon slightly different wordings for std::vector::erase() and std::deque::erase().

This is what C++14 says about std::deque::erase ([deque.modifiers]/4-6, emphasis mine):

> Effects: ...

> Complexity: The number of calls to the destructor is the same as the number of elements erased, but The number of calls to the assignment operator is no more than the lesser of the number of elements Before the erased elements and the number of elements after the erased elements.

> Throws: Nothing unless an exception is thrown by the copy constructor, move constructor, assignment operator, or move assignment operator of T.

And here is what it says about std::vector::erase ([vector.modifiers]/3-5):

> Effects: ...

> Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the move assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.

> Throws: Nothing unless an exception is thrown by the copy constructor, move constructor, assignment operator, or move assignment operator of T.

As you can see, the exception specifications for both of them are the same, but for std::vector it's explicitly mentioned that move assignment operator is called.

There's also requirement for T to be MoveAssignable for erase() to work with both std::vector and std::deque (Table 100), but this doesn't imply the presence of the move assignment operator: one can define a copy assignment operator, and not define move assignment operator, and this class will be MoveAssignable.

Just in case, I checked with GCC and Clang, and indeed std::vector::erase() calls copy assignment operator if there's no move assignment operator, and std::deque::erase() does the same (DEMO).

So the question is: did I miss something, or this is an (editorial) issue in the standard?

Update: I've submitted an LWG issue #2477.

C++ Solutions


Solution 1 - C++

At Lenexa meeting the issue got Immediate status with proposed resolution:

>This wording is relative to N4296. > >Change 23.3.3.4 [deque.modifiers]/5 to: > >-5- Complexity: The number of calls to the destructor of T is the same as the number of elements erased, but the number of calls to the assignment operator of T is no more than the lesser of the number of elements before the erased elements and the number of elements after the erased elements. > >Change 23.3.6.5 [vector.modifiers]/4 to: > >-4- Complexity: The destructor of T is called the number of times equal to the number of the elements erased, but the move assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.

That is, if the resolution is accepted there will be no special mention of the move assignment for std::vector::erase, and also the wording for std::deque::erase will be clarified a bit.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnton SavinView Question on Stackoverflow
Solution 1 - C++Anton SavinView Answer on Stackoverflow