Let's say we have a class template:

template< typename t >
class c;

and a function template:

template< typename t1, typename t2 >
bool operator ==
(
c< t1 > const&
, c< t2 > const&
);

Now we want operator ==< t1, t2 > to be a friend of class c< t3 > ONLY for t1 = t3 or t2 = t3. How do we specify this?

Re: friend templates by Carl

Carl
Thu Apr 13 21:03:14 CDT 2006

Angel Tsankov wrote:
> Let's say we have a class template:
>
> template< typename t >
> class c;
>
> and a function template:
>
> template< typename t1, typename t2 >
> bool operator ==
> (
> c< t1 > const&
> , c< t2 > const&
> );
>
> Now we want operator ==< t1, t2 > to be a friend of class c< t3 >
> ONLY for t1 = t3 or t2 = t3. How do we specify this?

I believe that according to the C++ standard, you cannot. What you need to
is declare a partial specialization of a function template as a friend, and
there's no such thing as partial specialization of function templates.

That said, the following does "work" on VC8 (I didn't test any other
version), but it's not portable:

// forward-declare the class template
template <class T> class X;

// forward-declare the function template
template <class T1, class T2> bool operator==(X<T1>const&,X<T2>const&);

// actual class definition
template <class T>
class X
{
T m;
template<class T1>
friend bool operator==(X<T1> const&, X<T> const&);

template<class T2>
friend bool operator==(X<T> const&, X<T2> const&);
};

// actual function definition
template <class T1, class T2>
bool operator == (X<T1>const& l, X<T2> const& r)
{
return l.m == r.m;
}

int main()
{
X<int> xi;
X<long> xl;
bool b = xi == xl;
}

-cd



Re: friend templates by John

John
Fri Apr 14 00:17:52 CDT 2006

"Carl Daniel [VC++ MVP]"
<cpdaniel_remove_this_and_nospam@mvps.org.nospam> wrote in message
news:uN8%23Xe2XGHA.3516@TK2MSFTNGP03.phx.gbl
> Angel Tsankov wrote:
>> Let's say we have a class template:
>>
>> template< typename t >
>> class c;
>>
>> and a function template:
>>
>> template< typename t1, typename t2 >
>> bool operator ==
>> (
>> c< t1 > const&
>> , c< t2 > const&
>> );
>>
>> Now we want operator ==< t1, t2 > to be a friend of class c< t3 >
>> ONLY for t1 = t3 or t2 = t3. How do we specify this?
>
> I believe that according to the C++ standard, you cannot. What you
> need to is declare a partial specialization of a function template as
> a friend, and there's no such thing as partial specialization of
> function templates.
> That said, the following does "work" on VC8 (I didn't test any other
> version), but it's not portable:
>
> // forward-declare the class template
> template <class T> class X;
>
> // forward-declare the function template
> template <class T1, class T2> bool
> operator==(X<T1>const&,X<T2>const&);
> // actual class definition
> template <class T>
> class X
> {
> T m;
> template<class T1>
> friend bool operator==(X<T1> const&, X<T> const&);
>
> template<class T2>
> friend bool operator==(X<T> const&, X<T2> const&);
> };
>
> // actual function definition
> template <class T1, class T2>
> bool operator == (X<T1>const& l, X<T2> const& r)
> {
> return l.m == r.m;
> }
>
> int main()
> {
> X<int> xi;
> X<long> xl;
> bool b = xi == xl;
> }
>
> -cd

It appears to work but doesn't really. Declare a global variable and modify
the operator definition as follows.

X<char> ch;

template <class T1, class T2>
bool operator == (X<T1>const& l, X<T2> const& r)
{
ch.m = 'a';

return l.m == r.m;
}

The call in main() means that l is of type int and r is of type long. Thus
friendship should not be granted to operator== by X<char>, so ch.m = 'a';
should not compile. Nevertheless, it does compile.

This matter has been previously discussed. Indeed, the question was asked by
the same person (under an alias). You answered it and an extended discussion
ensued, which Daveed Vandevoorde joined in.

http://groups.google.com/group/microsoft.public.vc.language/browse_frm/thread/ffa20d82f1c2eb0d/dd39bbfde8f45051?q=class+templates+and+friend+function+templates&rnum=1#dd39bbfde8f45051

I have been meaning to write up a bug report on this...taking a while I
know. Coming real soon.


--
John Carson




Re: friend templates by Carl

Carl
Fri Apr 14 09:00:30 CDT 2006

John Carson wrote:
> This matter has been previously discussed. Indeed, the question was
> asked by the same person (under an alias). You answered it and an extended
> discussion ensued, which Daveed Vandevoorde joined in.

Good memory! I knew it had a familiar ring to it...

-cd



Re: friend templates by Angel

Angel
Fri Apr 14 12:19:58 CDT 2006

>> This matter has been previously discussed. Indeed, the question was
>> asked by the same person (under an alias). You answered it and an extended
>> discussion ensued, which Daveed Vandevoorde joined in.
>
> Good memory! I knew it had a familiar ring to it...

OK, so I cannot have what I want...