Boost logo

Boost :

From: Dave Abrahams (abrahams_at_[hidden])
Date: 2000-04-20 21:47:08


on 4/20/00 10:11 AM, Gary Powell at Gary.Powell_at_[hidden] wrote:

>
>>> On adding stuff to std::, isn't this currently very much a live issue
>> for
>>> debate?
>>
> A formal request for changing the wording of the std was just made this week
> by Alan Griffths. The text was reprinted in comp.std.c++. Alan very clearly
> outlines the general problem of swap, and any other std algorithm.

Oh, listen, I know the issue is on the table: I was the one who submitted
the issue for consideration in the library working group at the Tokyo
meeting this week. I just don't expect any serious changes to the standard
in this area to come about for a good many months - probably a good bit
longer. The committee isn't even sure whether it is supposed to be making
serious changes such as this issue would require for the next few years.

>>> As Gary says "it's the best of a lot of worse choices" - I didn't
>>> read this as being a gratuitous violation of the standard, but more a
>>> compromise until the current issues on how to properly extend things
>> like
>>> std::swap for user-defined containers and template stuff is resolved.
>>
> Here is the problem as it relates to views.
>
> If you call std::swap(view a, view b), with out my overloading std::swap
> it will compile and probably do the wrong thing. Since std::swap knows
> nothing about views, you get a bitwise swapping of the data.

Not really; you get the standard semantics: "Exchanges values stored in two
locations", assuming the type is Assignable [and CopyConstructible - note
this is missing from the standard but there's no other way to implement it.
A DR has been submitted]. There is no "bitwise copying" involved.

> This may or may
> not be ok. There is just no way for the swap to know for sure that this is
> going to work. A view needs to pass off the swap to the container it is
> adapting. This could be a user container or a std one.

I don't know the details of your views library.

> If I overload std::swap, there is now no way for you to call the real
> std::swap(view,view); But it could be argued that this is never correct.

Why not? are your views CopyConstructible and Assignable? If not, using
std::swap() on them is an error. std::swap is not supposed to work in that
case.

> If you always write:
> using std::swap;
> swap(view, view)
>
> and I have my own swap in my namespace (which for the moment doesn't compile
> but I will work on this.) we can rely on Koening lookup to find the correct
> swap and use that.

Yes, I'm well aware of the available techniques and the drawbacks of each.

> Except the lookup doesn't do the right thing (as far as
> what I want THIS time.) if this is done in a member function. It finds the
> std swap only.

Koenig lookup doesn't operate differently inside member function bodies as
far as I know. Did I miss something?
 
> If you call a std algorithm, it must use the "using" trick to get the
> correct swap. And there is no way for you to know for sure short of reading
> the code that it will be done correctly. Plus it silently compiles making
> maintenance a nightmare.

No std algorithm is not required to use swap (except possibly reverse(), but
I think even that one is not required to use swap).

A std algorithm is not allowed to use swap except on types which are
otherwise required to be CopyConstructible and Assignable. If you are
passing a view which is not both CopyConstructible and Assignable to a
conforming standard algorithm which calls swap on it, you are in error. This
algorithm could just as easily have been implemented in terms of assignment
and copy construction, and if your code silently compiles it is still your
fault.

> I'd be glad to do the right thing. It just isn't clear to me what that is.
> So I did the the next best and did what seems to work on the majority of
> compilers. I had about a week of email with Alan over what to do about this
> and I settled on adding to std.
>
> Feel free to email me or post what you would prefer. I don't mind
> maintaining two versions, or having compile time flags to allow users to
> choose.

I think the bottom line is that std::swap() is just not all that important.
It isn't used by the standard algorithms, and it gives few guarantees,
***except when it is used on certain types provided by the standard
library***. When you use it on other arbitrary types (e.g. user-defined
types), you don't have any right to expect behavior other than roughly what
is given by:

  template<class T> void swap(T& a, T& b) { T tmp(b); b = a; a =tmp; }

It is futile to try to force it into being something more than what the
standard says it is. From the point of view of generic code std::swap() will
never be anything other than a function which exchanges two
CopyConstructible Assignable values using copy construction and assignment.

>>> On the forward declaration issues, just include the full headers - it's
>> just
>>> a compile time optimisation.
> No Problem.
>
> I just posted a patch file to the vault. It includes the two necessary
> changed files so that there is an optimization flag which can be set to use
> forward declarations of std containers. By default its off.
>
> I did leave the non standard but well used containers, slist, hash_set,
> hash_map, hash_multiset, hash_multimap, as forward declarations. They aren't
> std yet.

Sorry, but this is still a violation of the rules of the standard. You're
not allowed to declare anything in std.

-Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk