Re: Class templates and friend function templates



John Carson wrote:
>> Function template doesn't support partial specialization.
>
> I am aware that function templates cannot be partially
> specialised. However, at no point in the code I supplied
> is operator== specialised, either fully or partially. The
> issue is the specialisation of the *friend declaration*,
> not the specialisation of the operator. Friend
> declarations have their own rules regarding
> specialisation.
>
> It would appear in fact that, where friend declarations
> are concerned, partial specialisation is ruled out for
> *both* functions *and* classes. This is stated by
> Vandevoorde and Josuttis (C++ Templates: The Complete
> Guide, p. 117) and experimentation confirms it.

Unfortunately I don't have this book at hand. However, I
looked in the standard, paragraph 14.5.3/1. There are
several examples of template friends:

template<class T> class task;
template<class T> task<T>* preempt(task<T>*);

template<class T> class task {
// ...
friend void next_time();
friend void process(task<T>*);
friend task<T>* preempt<T>(task<T>*);
template<class C> friend int func(C);
friend class task<int>;
template<class P> friend class frd;
// ...
};

---
[...] each specialization of the `task' class template has
all specializations of the function template `func' as
friends.
---

I think it's the same case as our operator ==. It's enough
that friend's template arguments are different from class'
template arguments, so compiler is free to match any
friend's specialization then.

In addition, paragraph 14.5.3/4 states:

---
A template friend declaration specifies that all
specializations of that template, whether they are
implicitly instantiated (14.7.1), partially specialized
(14.5.4) or explicitly specialized (14.7.3), are friends of
the class containing the template friend declaration.
---

So, given all that, the specialization (from original post)

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

is a friend both of C<int> and C<float>. That answers the
question why it has an access to both instantiations if
C<T>.

> What is a little curious to me is that compilers will
> accept a friend declaration for a function that has the
> appearance of allowing a partial specialisation of the
> friend declaration, when in fact the friend declaration
> is not specialised at all. When I try to do something
> analogous with a class, it won't compile, e.g.,
>
> #include <iostream>
> using namespace std;
>
> template<class X, class Y>
> class B;
>
> template<class T>
> class A
> {
> template<class Other>
> friend class B; //won't compile, nor will friend
> //class B<T, Other>; int x;
> public:
> A(int x_) : x(x_)
> {}
> };

Actually, there is a missing template argument for B. When
you specify it, then code compiles without problems:

//...
template<class Other, class Whatever>
friend class B;

There can be T instead of Other or Whatever arguments.


.



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: does not compile with "using namespace std"
    ... That means that a specialisation of class Stack for some ... template parameter T will have the following function ... because you haven't provided a definition for the friend operator <<. ...
    (comp.lang.cpp)
  • Re: Determining a variables type
    ... what part of this solution makes use of partial template ... but essentially it boils down to the compiler chooses the most specialised ... This is the part that uses partial specialisation. ...
    (comp.lang.cpp)
  • Re: Implementing a templated "round" function?
    ... At the moment i have two different implementations, ... I did add a second template parameter S for the source type: ... > I could add a specialisation for every combination of S and T, ... template <typename T, typename S> ...
    (comp.lang.cpp)