Re: Class templates and friend function templates





John Carson wrote:
[...]
> Thanks for those remarks. I really appreciate you taking the time to
> comment.
>
> It never occurred to me that the friend declaration could be an overload.
> That certainly helps make sense of why the code compiles. I still have some
> questions, however. The following code compiles on both VC++ 8.0 (Beta 2)
> and Comeau Online.
>
> #include <iostream>
> using namespace std;
>
> template <class T>
> class C
> {
> public:
> C(int x_) : x(x_) {}
> private:
> int x;
>
> template <class Other>
> friend bool operator == (C<T>&, C<Other>&);
> };
>
> // global instance of C<int*>
> C<int*> c0(7);
>
> template <class U, class V>
> bool operator == (C<U>& u, C<V> &v)
> {
> // access private data of c0
> cout << c0.x;
>
> return u.x == v.x;
> }
>
> int main()
> {
> C<int> c1(1);
> C<float> c2(2);
> bool b = c1 == c2;
> return 0;
> }
>
> My questions concerning that code are:
>
> 1. If the friend declaration declares an overload, where is that overload
> defined?

In your example it is not defined. However, you can defined it
"inline" (i.e., as part of the friend declaration).

> (Comeau Online says it doesn't link, but "will instantiate all
> templates hence doing a fake link" --- I am not sure exactly what that means
> and whether it is relevant, but VC++ certainly links).

I suspect the online version uses an EDG option to "instantiate
every used template instance". However, it is not an actual link
operation.

Our demo compiler in its strict mode leads to the following
link error:

bool operator ==<T1>(C<int> &, C<T1> &) [with T1=float] t.o
ld: fatal: Symbol referencing errors. No output written to a.out

which is as expected.

> 2. If I have understood you correctly, the definitions of c0, c1 and c2
> should lead to the following overload friend declarations:
>
> template <class Other>
> friend bool operator == (C<int*>&, C<Other>&);
>
> template <class Other>
> friend bool operator == (C<int>&, C<Other>&);
>
> template <class Other>
> friend bool operator == (C<float>&, C<Other>&);
>
> respectively.

Correct.

> The line from main()
>
> bool b = c1 == c2;
>
> should lead to a call to
>
> operator == (C<int>&, C<float>&);

The signature you quote there isn't detailed enough.
The candidates are the three friend functions you
mention above and the template defined in your
example. Of those, the viable ones (i.e., the ones
that could resolve the "c1 == c2" expression) are

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

and

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

The deduced signatures of these two are equally good
(they're in fact the same types). Therefore, the concept of
"partial ordering of function templates" (section 14.5.5.2
in the standard) comes into play. In this case, the first
declaration (the friend) is selected and since it doesn't
have a definition, you get the linker error mentioned
above.

(You can tell the partial ordering by noticing that the
friend candidate "could be an instance" of the nonfriend
candidate, but not vice versa -- I'm talking function
types here.)

> I can't see where the friend declarations make this operator a friend of
> C<int*>, yet it can access the private data of c0, which is an instance of
> C<int*>. (For that matter, I can't see where the friend declarations make
> the operator a friend of C<float>.)

Note that the nonfriend template is never instantiated
and the access check (or error) is therefore never needed.

Daveed

.



Relevant Pages

  • Re: Class templates and friend function templates
    ... friend void process; ... each specialization of the `task' class template has all specializations of the function template `func' as friends. ... It only has one parameter that is distinct, thus implying a kind of partial specialisation of the friend declaration once C is instantiated for a particular type. ...
    (microsoft.public.vc.language)
  • Re: Class templates and friend function templates
    ... That certainly helps make sense of why the code compiles. ... If the friend declaration declares an overload, ... As for Comeau, I have used the online version for a long time as a test of correctness, but clearly I need the full version if I am to test some of the subtler template issues. ...
    (microsoft.public.vc.language)
  • Re: friend of template class
    ... doesn't actually enforce that) declare the template friend function, ... What actually happens here, is that when you instantiate the template class, ... can't give compiler a hint where to look for it's definition for the ...
    (alt.comp.lang.learn.c-cpp)
  • 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)

Loading