typedef of pair<> != pair<> in copy(); have to define pair<> derived class

Michael H. Cox mhcox@bluezoosoftware.com
Tue Feb 18 10:56:00 GMT 2003


Thanks for the explanation!  This ADL stuff is really wrecking having havoc
with my "C++ intuition" about whether something should compile or not.  Is
there any better way than the way I worked around this "feature", i.e.
declaring a derived class?  I tried two other ways:

1) Declaring a new name space and adding the typedef and I/O stream
operators to it.  That didn't work.  I suppose a typedef nested in a new
namespace doesn't affect the lookup rules.

2)  I "re-opened" that std namespace and added by custom I/O stream
operators and that worked, but I doubt that's an "approved solution".

I would think it would be not uncommon for an application-specific
instantiated std::pair<> template to need its own I/O stream operators.
This seems like a bug (or at least a missing feature).  Maybe C++0x should
declare, but not define some, e.g.

namespace std
{
  template <typename T1, typename T2>
  ostream& operator<<(ostream&, const pair<T1, T2>&);

  template <typename T1, typename T2>
  istream& operator>>(istream&, pair<T1, T2>&);
}

so a std library user could specialize/define them, e.g.:

typedef pair<string, int> Pathname
namespace std
{
  template<>
  ostream& operator<<(ostream&, const Pathname&)
  {
  }

  template<>
  istream& operator>>(istream&, Pathname&)
  {
  }
}

although I still don't like having to reopen a namespace I don't own.
Experimenting with this I noticed that

template<>
ostream& std::operator<<(ostream&, const pair<string, int>&)
{
}

template<>
istream& std::operator>>(istream&, pair<string, int>&)
{
}

doesn't compile (the last sentence of 14.7.3.2 (assuming the "global
namespace" encloses all namespaces) and a syntax error used the above format
on an earlier version of the code makes me think it might).  Another feature
or pilot error again :-)?

Looks like I'm going to have learn C++ all over again, now that compilers
are more conforming :-).  I reading "C++ Templates: The Complete Guide", but
it's tough reading, although easier than the ISO C++ standard.  Thanks
again!


Mike



> -----Original Message-----
> From: gdr@integrable-solutions.net [mailto:gdr@integrable-solutions.net]
> Sent: Tuesday, February 18, 2003 12:59 AM
> To: mhcox@bluezoosoftware.com
> Cc: GCC Help; GCC Bugs
> Subject: Re: typedef of pair<> != pair<> in copy(); have to define
> pair<> derived class
>
>
> "Michael H. Cox" <mhcox@bluezoosoftware.com> writes:
>
> | It seems like the following should compile (with USE_TYPEDEF=1), since a
> | typedef of a std::pair<> class should be equivalent to the std::pair<>
> | class.  To get it to compile, I had to declare a std::pair<>
> derived struct.
> | Is this a compiler bug or pilot error on my part?
>
> This is -not- a compiler bug.
>
> The compiler is behaving as mandated by the C++ standard.  The
> insertion operator "<<" -- used by std::copy() --  is looked up
> according to Argument Dependent Lookup (a.k.a. Koenig lookup).
> If Pathname is typedefed (in the global scope) then ADL will ignore
> the global scope because it is not an associated namespace of Pathname
> -- Pathname is synonymous to std::pair<> whose associated namespace is
> std:: augmented with the associated namespaces of the template arguments.
>
> -- Gaby



More information about the Gcc-help mailing list