Re: Class templates and friend function templates
- From: google@xxxxxxxxxxxxxxx
- Date: 26 Jul 2005 07:24:06 -0700
John Carson wrote:
[...]
> >> 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.
That's correct. The standard says that a friend of a class
or class template can be one of (14.5.3/1):
- a (primary) template (class or function)
- a nontemplate class or function
- a (full) specialization of a template
[...]
> I don't have any problem with that. What is curious is that in
>
> template <class T>
> class C
> {
> public:
> C(int x_) : x(x_) {}
>
> private:
> int x;
>
> template <class Other>
> friend bool operator == (C<T>&, C<Other>&);
> };
>
> operator== does not have two template parameters distinct from the template
> parameter of the enclosing class. 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. If this simply
> didn't compile, then the mystery would disappear. Seemingly, what is
> happening is that the T that appears in C<T>& in the operator's parameter
> list is treated as distinct from the T that is the template parameter for
> the class. But if that is the case, then you would expect that the compiler
> would require:
>
> template <class T, class Other>
> friend bool operator == (C<T>&, C<Other>&);
Not quite. The funny thing about friend declarations is that they are
indeed declarations: They are able to introduce ("inject") a new entity
in the stream of namespace scope declarations. Consider this example:
template<typename T> struct S;
template<typename T, typename U> void f(S<T>*, S<U>*) {} // (1)
template<typename T> struct S {
template<typename U> friend void f(S<T>*, S<U>*); // (2)
};
S<int> s; // (2)
Here, when S<int> gets instantiated (at point (2)), the friend
declaration
gets instantiated with it, and becomes a declaration of the following
template:
template<typename U> void f(S<int>*, S<U>*); // (3)
This is a primary template (there aren't partial specializations of
function
templates anyway) that has no connection to the template declared in
(1),
other than being an overloaded version of it. E.g., assuming an
implementation that uses mangled names, the mangled names for the
instances of (1) and (3) will be different.
Finally, I should note that because (3) was only declared as a friend
declaration, its visibility is limited. For example, if we removed the
declaration (1) (to avoid ambiguities), a call of the form
f(0, (S<float>*)0)
would not find the friend declaration because S<int> isn't an
associated class of either of the arguments (friend declarations are
only visible through a form of argument-dependent lookup).
(See section 9.2.2 in "C++ Templates" for a discussion of this.)
I hope that's helpful somehow.
Daveed
.
- Follow-Ups:
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- References:
- Class templates and friend function templates
- From: BigMan
- Re: Class templates and friend function templates
- From: Carl Daniel [VC++ MVP]
- Re: Class templates and friend function templates
- From: Carl Daniel [VC++ MVP]
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: Alex Blekhman
- Re: Class templates and friend function templates
- From: John Carson
- Re: Class templates and friend function templates
- From: Alex Blekhman
- Re: Class templates and friend function templates
- From: John Carson
- Class templates and friend function templates
- Prev by Date: Re: what is .net?
- Next by Date: Virtual Base Class Question
- Previous by thread: Re: Class templates and friend function templates
- Next by thread: Re: Class templates and friend function templates
- Index(es):
Relevant Pages
|
Loading