[Patch] Second half of tr1/complex

Howard Hinnant hhinnant@apple.com
Fri Jan 13 15:56:00 GMT 2006


On Jan 13, 2006, at 10:40 AM, Paolo Carlini wrote:

> Howard Hinnant wrote:
>
>>> (*) Is it even legal using the 'arg' name together with a using
>>> namespace like this?!?
>>
>> <nod> It's legal.
>
> I can trust you, but I want to understand in detail. Isn't true that
> 'arg' is a reserved name? Otherwise, if the user can use 'arg' in any
> way, then do 'using ...arg', conflicts are always going to occur, one
> way, or another.

Let's look at it from another viewpoint.  I got lazy when demo'ing  
the problem with the using namespace std::tr1.  It can happen without  
it.

Consider (I'm coding without testing, hope this works!):

#include <tr1/complex>
#include <tr1/memory>

namespace mine {

template <class T>
struct small {};

template <class T>
struct big
{
     big() {}
     big(small<T>) {}
};

big<std::tr1::shared_ptr<int> > arg(const  
big<std::tr1::shared_ptr<int> >&)
    {return big<std::tr1::shared_ptr<int> >();}

} // mine

int main()
{
    using namespace mine;
    big<std::tr1::shared_ptr<int> > b = arg 
(small<std::tr1::shared_ptr<int> >());
}

I believe you'll get the same problem again here.  Because a std::tr1  
component is part of small's template parameter list, std::tr1 is  
included during ADL.  And again, the overly generic arg will be a  
better (but unintended) match.  This is even though we much more  
carefully placed our code in our own namespace and only opened that  
namespace at function scope.

This also could have happened by deriving small from some std::tr1  
object (even privately) instead of using a template parameter.  ADL  
can effectively open and look into namespaces in a fairly subtle manner.

-Howard



More information about the Libstdc++ mailing list