Can I use std::move more than once when assigning to different base classes?

Viewed 106
HashTable & operator= (HashTable && rhs)
{
    destroyElements();
    free();

    std::swap(buf, rhs.buf);
    std::swap(m_size, rhs.m_size);
    std::swap(grower, rhs.grower);

    Hash::operator=(std::move(rhs));
    Allocator::operator=(std::move(rhs));
    Cell::State::operator=(std::move(rhs));
    ZeroValueStorage<Cell::need_zero_value_storage, Cell>::operator=(std::move(rhs));

    return *this;
}

Does rhs become invalid after the call to Hash::operator=?

1 Answers

Assuming neither of those bases does something obscene like mess with the state of the other bases, then it should be fine.

Hash::operator=(std::move(rhs));

The cast to an rvalue produces a HashTable&& here. That in turn can be implicitly bound to a Hash&& (assuming an accessible and unambiguous base). So the operator only operates on the Hash sub-object. And you do not access that object again, following the guideline of not using an object after it has been moved from.

Same goes for the other bases.

All in all, if your classes are well-behaved and maintain their own invariants correctly during move assignment. this is a viable way to implement the move. Heck, even a defaulted move operation delegates to the move operations of bases.

Related