Topic: Partial specialization on class template member functions


Author: "Edward Diener" <eldiener@earthlink.net>
Date: Tue, 9 Apr 2002 19:32:08 GMT
Raw View
C++ has the ability to explicitly specialize an entire class template
definition as well as to explicitly specialize a class template member
function.

C++ has the ability to explicitly partially specialize an entire class
template definition.

What are the factors which have mitigated against C++ having the ability to
explicitly partially specialize a class template member function ?

As an example:

-----------------------------------------------

template<typename Parm1, typename Parm2>
class TwoType
{
void SomeFunction(Parm1 x,Parm2 y) { };
// .... Many other functions
};

-----------------------------------------------

I now need to partially specialize on SomeFunction when Parm1 is an "int"
and Parm2 is any other type, but can not do that directly in C++. What I can
do, which I believe works, but feels like a hack is:

------------------------------------------------

template<typename Parm1, typename Parm2>
class TwoType
{
void SomeFunction(Parm1 x,Parm2 y) { SomeFunctionInternal(x,y)}
// .... Many other functions
template<typename U,typename V> void SomeFunctionInternal(U x,V y) {// ...
using U and V};
template<typename V> void SomeFunctionInternal(int x,V y) {// ... using int
and V}
};

--------------------------------------------------

What I would prefer to do is:

template<typename V> void TwoType<int,V>::SomeFunction(int x,V y) { // ...
using int and V }

Furthermore the hack using function template member functions does not
directly work if SomeFunction does not take parameters of the template types
but wants to use those types internally, since both member function
signatures will be the same with no parameters, while with partial
specialization of a class template member function one could still write:

template<typename V> void TwoType<int,V>::SomeFunction() { // ... using int
and V }

and it would theoretically work correctly if it was allowed. So I am
interested in why it is not allowed in C++ because I am sure its not being
part of the C++ language means that there is something I have overlooked or
don't understand.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Nicola Musatti <objectway@divalsim.it>
Date: Thu, 11 Apr 2002 18:42:26 GMT
Raw View
Hallo, Ed.

Edward Diener wrote:
>
> C++ has the ability to explicitly specialize an entire class template
> definition as well as to explicitly specialize a class template member
> function.
>
> C++ has the ability to explicitly partially specialize an entire class
> template definition.
>
> What are the factors which have mitigated against C++ having the ability to
> explicitly partially specialize a class template member function ?

If I understood you correctly I share your point of view. Let's see if
we agree:

If I have

template <class T1, class T2> class A {
  void f();
  void g();
};

template <class T1, class T2> void A<T1,T2>::f() {}
template <class T1, class T2> void A<T1,T2>::g() {}

I can provide a complete explicit specialization, such as:

template <> class A<int,float> {
  void f();
  void g();
};

void A<int,float>::f() { g(); }
void A<int,float>::g() {}

Or I can provide an incomplete explicit specializazion of A as follows:

template <> void A<int,float>::f() { g(); }

In this case the specialization of the class declaration and of member
function g() are implictly obtained from the base template.

However, if I want to partially specialize A I have to provide a
complete definition for my specialization, e.g.:

template <class T2> class A<int,T2> {
  void f();
  void g();
};

template <class T2> void A<int,T2>::f() { g(); }  // [1]
template <class T2> void A<int,T2>::g() {}

What I would like to do, but cannot, is to only provide a definition for
the member functions that actually change from the base template:

template <class T2> void A<int,T2>::f() { g(); }  // [2]

And have both the class declaration and member function g() for this
partial specialization implicitly obtained from the base template.

One objection comes immediately to mind: as [1] and [2] above have
identical syntax, how can I distinguish them, that is how can the
compiler tell if an explicit partial specialization for the class
declaration should be expected or not.

Would it be possible to overcome this difficulty?

Cheers,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Edward Diener" <eldiener@earthlink.net>
Date: Thu, 11 Apr 2002 21:42:04 GMT
Raw View
"Nicola Musatti" <objectway@divalsim.it> wrote in message
news:3CB586F9.DB7AF684@divalsim.it...
> Hallo, Ed.
>
> Edward Diener wrote:
> >
> > C++ has the ability to explicitly specialize an entire class template
> > definition as well as to explicitly specialize a class template member
> > function.
> >
> > C++ has the ability to explicitly partially specialize an entire class
> > template definition.
> >
> > What are the factors which have mitigated against C++ having the ability
to
> > explicitly partially specialize a class template member function ?
>
> If I understood you correctly I share your point of view. Let's see if
> we agree:
>
> If I have
>
> template <class T1, class T2> class A {
>   void f();
>   void g();
> };
>
> template <class T1, class T2> void A<T1,T2>::f() {}
> template <class T1, class T2> void A<T1,T2>::g() {}
>
> I can provide a complete explicit specialization, such as:
>
> template <> class A<int,float> {
>   void f();
>   void g();
> };
>
> void A<int,float>::f() { g(); }
> void A<int,float>::g() {}
>

Agreed.

> Or I can provide an incomplete explicit specializazion of A as follows:
>
> template <> void A<int,float>::f() { g(); }
>
> In this case the specialization of the class declaration and of member
> function g() are implictly obtained from the base template.

Agreed.

> However, if I want to partially specialize A I have to provide a
> complete definition for my specialization, e.g.:
>
> template <class T2> class A<int,T2> {
>   void f();
>   void g();
> };
>
> template <class T2> void A<int,T2>::f() { g(); }  // [1]
> template <class T2> void A<int,T2>::g() {}

Agreed.

> What I would like to do, but cannot, is to only provide a definition for
> the member functions that actually change from the base template:
>
> template <class T2> void A<int,T2>::f() { g(); }  // [2]
>
> And have both the class declaration and member function g() for this
> partial specialization implicitly obtained from the base template.

Yes, my point.

> One objection comes immediately to mind: as [1] and [2] above have
> identical syntax, how can I distinguish them, that is how can the
> compiler tell if an explicit partial specialization for the class
> declaration should be expected or not.

If you partially specialize on the class template, which is currently the
only kind of partial specialization which can exist, you have no need to
partially specialize on a class template member function using the same
partial specialization since you have already, by definition, done it.

At the point of instantiation, if [2] is seen and [1] along with its
partially specialized class template is not, then [2] becomes the partial
specialization for the class template member function, and all other calls
to the class template member function which does not match the partial
specialization goes to the original class template or to whatever other
specializations or partial specializations which are seen.

If both [1] and [2] are seen at the time of instantiation, then it is the
same error as any duplicate function signature within the same scope.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]