https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98473
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Complete example:
#include <vector>
struct X {
X();
X(const X&);
X& operator=(const X&) = delete; // !!
X(X&&) noexcept;
X& operator=(X&&) noexcept;
int data = 54;
};
void add_to_front(std::vector<X>& a, const std::vector<X>& b) {
a.insert(a.begin(), b.begin(), b.end());
}
(In reply to Borislav Stanimirov from comment #0)
> It doesn't compile. My guess is that code which will never get invoked,
> still needs to compile (or, worse yet, copy assignment does get invoked?!)
When a.capacity() > a.b.size() the elements from b are copied over existing
elements of a using std::copy, which uses copy assignment.
To meet the requirements of the standard we would need to insert them at the
end and then use std::rotate to reposition them.
I see that libc++ has the same behaviour as libstdc++, which does make me think
the standard is wrong to require this (since it doesn't reflect reality). I'll
have to check the history of the standard.
> This does compile and work on msvc, so a compile-time check for the
> copy-assignment code is possible.
No, you can't check that at compile time. It's a dynamic condition. Presumably
MSVC uses std::rotate instead so no check is needed.