Boost logo

Boost :

From: Alan Griffiths (alan_at_[hidden])
Date: 2000-04-08 06:12:22


In message <B51369A7.645C%darin_at_[hidden]>, Darin Adler
<darin_at_[hidden]> writes
>on 4/7/00 8:39 AM, Gary Powell at Gary.Powell_at_[hidden] wrote:
>
>> Also is there a consensus on use of std::swap? In the views code we added
>> specializations of std::swap(viewType&,viewType&) [...]
>>
>> namespace std {
>> swap(viewType &a,viewType &b)
>> {
>> a.swap(b);
>> }
>> }
>>
>> I've been following a discussion in C.L.C++.M on swap and I'm confused. Is
>> it illegal to make more std::swap() specializations?

No this is fine - although adherents of option "A" (below) would
probably advise against since it is inconsistent with the more general
case.

It is overloading that is illegal. That is:

    namespace boost { template<typename element> class container; }

    namespace std {
        template<typename element>
        void swap(::boost::container&, ::boost::container&);
    }

The thread on C.L.C++.M deals with the problem of handling class
templates as parameters.

>Should my swap
>> functions be in my own namespace? Should my swap function do this?
>>
>> void swap(view &a)
>> {
>> using std::swap;
>> swap(base,a.base);
>> }
>>
>> Will the Koening lookup rules find the correct swap inside my function?

Provided that this is not a member function.<g>

If it is a member function, then it will find std::swap<>. (Argument
dependent lookup aborts if a class member function name matches.)

>>Will
>> the stand library algorithms use my swap inside their functions?

That is the subject of a separate thread on com.std.c++.

>> Any help on this will cause us to fix and adjust.
>
>There's no consensus yet on the whole thing, but there seem to be two
>self-consistent views:
>
>A: Use Koenig Lookup:
>
>The standard does prohibit the kind of overload you show above. It's not
>"partial specialization of a function template", because that doesn't exist!
>All uses of functions from namespace std must use unqualified names to get
>full advantage of Koenig Lookup, so you need to do the "using" as above.
>Standard library implementations ought to always use unqualified names too;
>perhaps the standard should be amended to require this. Names like "swap" in
>other namespaces are "reserved"; you must not use them for other purposes
>because they might cause trouble for the standard algorithms; perhaps the
>standard should be amended to make this clear.

This is the only option that doesn't require a change to the standard!

But it is far from clear that this is the intent of the committee.

If this was the intent, then the implications for the use of names in
other namespaces are not made clear (especially for names that will be
added to std in the future). Further it would have been desirable for
the standard to include a set of utility functions like:

namespace std
{
    template<typename _T>
    inline void resolve_swap(_T& _Ta, _T& _Tb)
    {
        using std::swap;
        swap(_Ta, _Tb);
    }
}

Otherwise everyone needs to write such functions for themselves. The
average programmer on the street (including myself until I was forced to
investigate the issues) will not see the need for this. It is fragile,
and errors do not cause a diagnostic.

>B: Allow Overloading In Namespace std:
>
>Although the standard does prohibit the kind of overload you show above, it
>would be better if it didn't; perhaps the standard should be amended to
>allow this. All uses of functions from namespace std by the library should
>use qualified names, and you need not do the "using" as above. Standard
>library implementations ought not use unqualified names either; perhaps the
>standard should be amended to require this. (It's not clear what to do about
>operators like <<. Should calls to even these be qualified with std:: in
>library implementations?)

This is the approach I favour. Not least because it works - in practice
- with all compilers and library implementations that I am aware of. I
really don't approve of relying on undefined behaviour in this way but
it is the only way I can support the idioms that users of my classes
come up with.

As Darin indicates there are problems with it - especially in wording
the necessary change to the standard. Many of the more obvious wordings
will allow additions to std that break conforming code.

For completeness there are two other views whose adherents believe them
to be self consistent...

C: Allow partial template function specialisation

Many of the problems with approach B come from the overload resolution
mechanism. This could be side-stepped by allowing a hypothetical
language feature to permit a function template to be partially
specialised on a generic type.

D: Change the "Koenig" name lookup rules

I cannot imagine how this could be done without breaking existing code -
and no-one has yet come up with a concrete proposal to convince me
otherwise.

-- 
Alan Griffiths  (alan_at_[hidden])  http://www.octopull.demon.co.uk/
ACCU Chairman   (chair_at_[hidden])             http://www.accu.org/

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