http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61023

--- Comment #4 from Nevin Liber <nevin at eviloverlord dot com> ---
Good point about the Standard.

However, the current behavior for move assignment breaks the invariant of the
container, since the comparator is what enforces the insertion ordering and
element equivalence.

Take for example:

struct Compare
{
    Compare(bool b) : b_(b) {}

    bool operator()(int l, int r) const
    { return b_ ? r < l : l < r; }

    bool b_;
};

int main()
{
    typedef std::set<int, Compare> S;

    S s(Compare(false));
    s.insert(2);
    s.insert(3);

    S abracadabra(Compare(true));

    // The heisenbug 3...
    abracadabra = std::move(s);
    assert(abracadabra.find(2) == std::find(abracadabra.begin(),
abracadabra.end(), 2)); // works
    assert(abracadabra.find(3) == std::find(abracadabra.begin(),
abracadabra.end(), 3)); // fails
}


This behavior seems untenable to me.

The implementation needs to do something more reasonable.  Even something as
drastic as deleting the ordered associative container move assignment when
stateful comparators are involved is better than the status quo.

Reply via email to