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.

Reply via email to