[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