Boost logo

Boost :

From: Fernando Cacciola (fernando_cacciola_at_[hidden])
Date: 2003-08-06 09:46:38


David Abrahams <dave_at_[hidden]> wrote in message
news:uptjjyodc.fsf_at_boost-consulting.com...
> "Fernando Cacciola" <fernando_cacciola_at_[hidden]> writes:
>
> >> I'm trying to say that I think it's the wrong patch. The right patch
> >> would put the swap specialization into _STL::.
> >>
> > It actually sufixes
>
> I assume you mean "suffices".
>
:-) yes

> > to put any 'std' extension in a nested namespace (say, stdx); then
> > injecting the names in 'std'.
>
> That's unfortunately illegal. You're not allowed to add names to
> std,

Oh Right...
I guess adding a namespace counts as adding a name.

>and anyway I don't see how it could help if you want to
> specialize something in std. Am I missing something?
>
If the specialization is injected into 'std' via
a using directive, as in

namespace std { using namespace stdx ; }

the problem goes away (the primary swap<> is now found).

The idea is to mimic the way the primary swap<> is defined
to avoid the conflict in as much a configuration-independent way
as possible.
STLPort (as shiped with BCB6) has various configuration flags
that affect the place were std names are effectively placed.

The following excrept from "stl\_config.h" shows the possibilities:

# if defined (_STLP_USE_OWN_NAMESPACE)
# ifdef _STLP_DEBUG
# define _STLP_STD _STLD
# else
# define _STLP_STD _STL
# endif
# else
# ifdef _STLP_DEBUG
# define _STLP_STD stdD
# else
# define _STLP_STD std
# endif
# endif

Names are declared/defined within _STLP_STD, where the actual value of
_STLP_STD depends on _STLP_USE_OWN_NAMESPACE and _STLP_DEBUG.
With the default configuration (the only one that really works with BCB6),
_STLP_STD=_STL

ALl these names are brought into 'std' by a using directive,
as shown by the following excrept from "stl/_epilog.h"

# if defined (_STLP_REDEFINE_STD) || ! defined (_STLP_USE_NAMESPACES)
// We redefine "std" to "stlport", so that user code may use std:: transparently
# undef std

# if defined(__cplusplus)

# ifndef _STLP_CONFIG_H
# include <stl/_config>
# endif

namespace _STLP_STD { }

namespace std {
using namespace _STLP_STD;
}

# endif // __cplusplus

# endif

The conflict sown by Alisdair arises from the fact that
"std" names are actually in a nested namespace and injected
into namespace std.
According to 3.4.3.2/2, if 'swap' is found _directly_
in namespace std, then the nested namespace _STLP_STD is not
looked up. This is why the mere presence of a function
named 'swap' hides the primary swap<>.
The problem ocurrs even if the 'swap' in 'std' is not
a specialization but any function with that name.

The idea of my workaround was to put the specialization
at the same 'level': in a nested namespace and not in 'std' directly.

As I realize now it is illegal to do that.

Anyway, the alternative workaround is to put
the specializations right in _STLP_STD (as you suggested)
(but not in _STL as that is just one of the possible actual namespaces,
depending on the configuration).

Similarly, qualified names should use _STLP_STD
(and not _STL for the same reasons as above).

BTW, I have a question:

According to BCB, the primary swap is hidden when some swap is
declared directly in std even for ADL.
That is, not even this works:

using std::swap; swap(x,y);

is this conformant?
I can't decipher the Standard on this matter.

Fernando Cacciola


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