Re: Class templates and friend function templates



"Carl Daniel [VC++ MVP]"
<cpdaniel_remove_this_and_nospam@xxxxxxxxxxxxxxx> wrote in message
news:envtI99jFHA.3936@xxxxxxxxxxxxxxxxxxxx
Carl Daniel [VC++ MVP] wrote:

template <class U,class V>
friend bool operator == <T>(U u, V v);

should be:

template <class U,class V>
friend bool operator == <T>(C<U> u, C<V> v);

Oddly, VC++ likes it either way, Comeau likes neither.  More than
likely it's a VC bug that this code compiles (and appears to behave
as desired).
-cd


Hi Carl,

I have been playing with this for the past several hours.

Your code can be made to compile on Comeau if you make the friend
declaration as follows:

template <class U,class V>
friend bool operator ==(C<U> u, C<V> v);

i.e., ditch the <T> (of course, one would normally use references).

I presume that your use of <T> is meant to tie friendship to an "own"
instantiation of the class. The following attempts to make such a tie. It
compiles on both Comeau and VC++ 8.0 Beta 2, but fails to enforce the tie
(see below):

template <class T>
class C;

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

template <class T>
class C
{
public:
    C(int x_) : x(x_) {}

private:
    int x;

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

template <class U, class V>
bool operator == (C<U>& u, C<V> &v)
{
    return u.x == v.x;
}

int main()
{
    C<int> c1(1);
    C<float> c2(2);
    bool b = c1 == c2;
    return 0;
}

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++.

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.

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.

I would be grateful for any insight you might offer.

--
John Carson

.



Relevant Pages

  • Re: Layout in memory
    ... pa@see.signature.invalid wrote in message news: ... Now suppose I have a subroutine like: ... Suppose then that my friend compiles this_mod and main with Compiler2. ...
    (comp.lang.fortran)
  • Re: Access Violation error while using pointers
    ... This code compiles and executes perfectly in Boreland C++. ... A string literal is itself an object, and its type is "array of const char" ...
    (microsoft.public.vc.debugger)
  • 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: Ridiculous size of executable? [OT}
    ... >Al puzzuoli wrote: ... >> The code compiles and runs, but I noticed that the size of ... <snip code> ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Template function as argument to another template function
    ... >> The following code compiles and executes properly on one compiler ... > As you see intel needs a real instantiation of the templated function, ...
    (comp.lang.cpp)