Boost logo

Boost :

Subject: Re: [boost] [move][container] Review Request (new versions of Boost.Move and Boost.Container in sandbox and vault)
From: Thomas Klimpel (Thomas.Klimpel_at_[hidden])
Date: 2009-10-18 09:38:43

Howard Hinnant wrote:
> I don't believe the standard should really tell you, much less try to
> enforce, how you write your move assignment operator.

I don't know about what the standard should do. I came to this discussion, because I did some sort of mini-review of the proposed "Boost.Move" library. The Adobe Move Library might have many drawbacks, but its documentation has a section "Implementing a Movable Type", which clearly states the requirements for a "Movable Type" (with respect to the Adobe Move Library). I have the opinion that it will reduce the usefulness of the proposed "Boost.Move" library, if the requirements for a "Copyable and Movable" and a "Movable but Non-Copyable" type (with respect to the proposed "Boost.Move" library) can't be clearly stated (or if there is no agreement on these requirements).

> I think it would be safe for the std::lib to promise you that
> it won't self-move-assign your objects, with the possible
> exception of you calling std::swap(x, x).

What about "std::copy" used together with "std::move_iterator"?

> Yes, you should be allowed to check for self-move-assignement, or
> assert on it, or whatever is best for your code. You should probably
> refrain from self-move-assigning std types such as vector.

I think the deeper reason for your position is that you want to propose a statement like "If a function argument binds to an rvalue reference parameter, the C++ standard library may assume that this parameter is a unique reference to this argument." for the standard.

I really liked that statement, because I thought all that mattered for it was the semantics of "std::move", and that it would only make sense that whoever called "std::move" also had to ensure that the result could be treated like a true rvalue. But I had to learn that any function returning an rvalue-reference would be in the same boat as "std::move" (I don't know whether this is good or bad). I also had hoped that "T&&" could have a semantics quite close to the semantics of "T", but it won't work. The reason is that even true rvalues will not always be destroyed "early" enough, so there is no way to make the semantics of "T&&" similar to the semantics of "T".

So std::swap(x,x) might actually be the more crucial question. When anybody is allowed to assert on self-move-assignment, std::swap(x,x) might become invalid, if std::swap isn't fixed. Two weeks ago, I thought that it would be easy to fix std::swap:

template <class T> swap(T& a, T& b) {
  if (&a != &b) {
    T tmp(std::move(a));
    a = std::move(b);
    b = std::move(tmp);

However, I realized today that this fix would be a huge regression, because it would slow down std::swap for POD types, i.e. exactly the types that std::swap is typically used for.

Changing the semantics of std::swap(x,x) is not really an option in my opinion, and I don't think that inventing more complicated fixes for std::swap would really solve this issue. One option would be to not move-enable std::swap at all, but the better option is probably to allow self-move-assignment at least in the case where the object has just been moved-from.

If there would be agreement between the authors of the move proposal (Howard E. Hinnant, Peter Dimov and Dave Abrahams) on any reasonable option how to solve this, I would have no problem with it. But if the only agreement is that no agreement is needed, then I'm a bit confused.

My own opinion is that I would love to see "T&&" have a semantics similar to "T", but it seems that this is not possible. A statement like "If a function argument binds to an rvalue reference parameter, the C++ standard library may assume that this parameter is a unique reference to this argument." would also be nice, but here we run into problems with std::swap (but to not move-enable std::swap would solve these). And because the entire topic is much less trivial than it looks at first sight, I have the impression that erring on the safe side is the better idea, hence self-move-assignment should be allowed.


Boost list run by bdawes at, gregod at, cpdaniel at, john at