Re: Class templates and friend function templates
- From: google@xxxxxxxxxxxxxxx
- Date: 27 Jul 2005 06:33:12 -0700
John Carson wrote:
[...]
> VC++, on the other hand, is doing at least two things wrong:
Our (EDG) compiler has a "Microsoft bugs" mode that also
emulates this. I looked it up in our documentation...
> 1. It is instantiating an instance of the operator from
>
> template <class U, class V>
> bool operator == (C<U>& u, C<V> &v)
> {
> cout << c0.x;
> return u.x == v.x;
> }
>
> when it should instead be producing a link error for the more specialised
> form of the operator declared in the friend declaration.
>
> 2. It is granting this operator friendship rights that it shouldn't have.
While this is true, they are both the consequence of the same bug:
Microsoft compilers seem to treat friend function declarations as
what used to be known as "guiding function declarations". (I meant
to write about those in the "C++ Templates" book, but it somehow
never made it into the text.) A "guiding function declaration" was a
declaration of an instance of a template. It was different from an
explicit specialization in that it did not inhibit the instance from
being generated. (The ARM hints at the existence of guiding
functions and for a while they were formally specified in the
Working Paper that eventually became the C++ standard. They were
removed from the standard when the notion of "signature" was
finalized, if I remember correctly.)
So what's happening in the example is that the friend declaration
injected by MSVC++ is _not_ equivalent to
template<typename Other>
bool operator==(C<int>&, C<Other>&);
but to some other construct that can no longer be expressed in
standard C++ (and in fact, I don't think the parameterized form
was ever possible). For argument's sake:
__guide template<typename Other>
bool operator==(C<int>&, C<Other>&);
This "guiding declaration" gets matched to a template declaration
that _follows_ it (a rather funny concept for C++, IMO). The final
result is that a subset of instances is made a friend of the class,
which is in fact what the original poster wanted. You can verify
this by replacing "C<Other>" in the friend declaration by "C<Other*>":
I think that will result in access errors.
(Note that this analysis is based on observation alone. The MSVC++
compiler may very well work completely differently internally.)
As you can imagine, figuring out that kind of stuff and emulating
the associated bugs in an otherwise standard compiler is loads of
fun ;-)
Daveed
.
- Follow-Ups:
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- References:
- Class templates and friend function templates
- From: BigMan
- Re: Class templates and friend function templates
- From: Carl Daniel [VC++ MVP]
- Re: Class templates and friend function templates
- From: Carl Daniel [VC++ MVP]
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: Alex Blekhman
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: Alex Blekhman
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: google
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: google
- Re: Class templates and friend function templates
- From: John Carson
- Class templates and friend function templates
- Prev by Date: Re: Where did my warnings go?
- Next by Date: Re: Virtual Base Class Question
- Previous by thread: Re: Class templates and friend function templates
- Next by thread: Re: Class templates and friend function templates
- Index(es):
Relevant Pages
|