Re: Class templates and friend function templates



John Carson wrote:
> [...]
> The thing that puzzled me is this. When c1 is declared, I
> expected the friend declaration to resolve to:
>
> template<class Other>
> friend bool operator == (C<int>&, C<Other>&);
>
> as a friend of C<int>. When c2 is declared, I expected
> the friend declaration to resolve to:
>
> template<class Other>
> friend bool operator == (C<float>&, C<Other>&);
>
> as a friend of C<float>.
>
> When c1 == c2 is evaluated, the operator called is:
>
> bool operator == (C<int>&, C<float>&);
>
> From what I have said above, I expected this to be a
> friend of C<int>
> but not of C<float>. Yet it is apparently a friend of
> both according to both Comeau and VC++.

The confusion stems from the expectation that function
template instantiation is similar to class template
instantiation. Actually, they're quite different. Class
templates support partial specialization. Partially
spesialized type of class participates in type resolution on
par with primary template.

Function template doesn't support partial specialization.
Function templates can overload each other, though.
Therefore, when compiler search for suitable function
template it doesn't distinguish between

bool operator == (C<int>&, C<Other>&);

and

bool operator == (C<float>&, C<Other>&);

All what compiler sees is:

template <class U, class V>
bool operator ==(C<U>&,C<V>&);

That is, _each_ specialization of class C will have _all_
specializations of operator == as friend. Only then, when
choice is locked (i.e., appropriate instance of operator ==
is generated), will compiler check for any particular
specialization of operator ==.

> Further experimentation shows that the tying doesn't
> actually work at all. If I define a global variable
>
> C<int*> c0(0);
>
> then I can access its private data inside the assignment
> operator called on c1 and c2 even though c0 is of a
> different type to both c1 and c2.

Yes, this happens because given template arguments

template <class U, class V>

will suit any type T of C<T>, so compiler free to choose
(and generate) operator == as it wishes.

> It would seem that my expectations concerning what friend
> declarations resolve to were mistaken. This may be because
>
> template<class Other>
> friend bool operator == (C<int>&, C<Other>&);
>
> would represent a kind of partial specialisation.

As I wrote above, function templates don't have partial
specialization. All functions templates are primary
templates and compete equally.

I'm not sure whether is it possible to tie

template <class U, class V>
bool operator ==(C<U>&, C<V>&);

to C<T> somehow. The best you can do is to provide
specialization for each desired pair of types:

template <>
bool operator == (C<int> u, C<float> v) { ... }

template <>
bool operator == (C<int*> u, C<float> v) { ... }

etc..

HTH
Alex


.



Relevant Pages

  • Re: Circular Class Template Friendship
    ... > My issue is the syntax of declaring a friend class within ... > which the string is a fixed width that is specialized. ... it is still possible to have Name_Id_Table template ... the friend class declaration. ...
    (comp.lang.cpp)
  • Re: Template friendship to nested template class
    ... friend struct INNER; ... Probably you are missing an EXTRA template to declare ... I think it's because the name referred to in a 'friend' declaration is looked up to exist at the namespace scope. ...
    (microsoft.public.vc.language)
  • Re: friend class in template
    ... This template takes 3 type parameters, the first of which is named ... The friend declaration attempts to declare the class ... the friend declaration doesn't do what the author apparently ... thought it would do (at least not on a conforming compiler). ...
    (microsoft.public.vc.language)
  • Re: OK in Visual C++6.0 but not in Visual C++ .NET 2003?
    ... it's a quirk of friend declarations. ... declaration, if no matching function is already visible, then a suitable ... template unless the friend declaration names a template (template ... friend void f).. ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Errors in VC program with gdiplus
    ... template argument list ... : see declaration of 'iterator' ...
    (microsoft.public.vc.mfc)

Loading