Topic: standard not clear about member function partial specialization


Author: invalid@yahoo.co.nz (Graeme Prentice)
Date: Mon, 5 Jan 2004 02:07:21 +0000 (UTC)
Raw View
On Mon, 29 Dec 2003 00:14:04 +0000 (UTC), SainTiss wrote:

>Hi,
>
>I've been looking into the standard for a clear statement on whether partial
>specialization of member functions of class templates is allowed or not.
>
>14.7.3/4 says that explicit specialization of a member function is legal,
>but doesn't state that partial specialization is not.


All 21 paragraphs of 14.7.3 are devoted entirely to explicit
specialization (of various sorts).

>
>One might argue that the standard indicates that partial specialization
>implies a distinct template, and therefore defining a member function
>requires the specialized class to be defined as well (explicitly
>instantiated).
>However, I don't find that very clear in the standard...
>
>Did I just misinterpret some sections, or is this really somewhat blurry?

14.5.4 is devoted  entirely to class template partial specializations -
The title of
14.5.4.2 Partial ordering of class template specializations
could perhaps be
14.5.4.2 Partial ordering of class template partial specializations

and similarly 14.5.4.3.

The fact that the standard doesn't describe any means of "partially
specialising" a non template member function of a template class is
sufficient indication that it is not allowed.  However, it wouldn't hurt
for 14.5.1.1 (Member functions of class templates), to mention that non
template member functions of a template class can be explicitly
specialized (and refer to the example in para 16 of 14.7.3) and to also
mention that partial specialization of a non template member function of
a template class is not allowed.  Note, para 16 of 14.7.3 has been
corrected in TC1 (C++ 2003).

If you look at the example in 14.7.3 para 5, it shows how to define an
out of class member function of an explicitly specialized template class
- it looks like this
         void A<int>::f() { /* ... */ }

note there is no "template <>" prefix on this definition.  This
distinguishes it from an explicit specialization of a member of a
template class when there is no corresponding explicitly specialized
template class - as shown in 14.7.3 para 16
       template<> void A<int>::f(int);

For the case of partial specialization, if you take the example in
14.7.3 para 16
    template<class T> struct A {
          void f(T);
          template<class X> void g(T,X);
          void h(T) { }
       };

You could attempt to define a partial specialization of f() as e.g.

template <typename T1>
void A<T1*>::f(T1*) {}
as in 14.5.4.3 para 1, but this is not allowed.  I do not know if the
reason was anything to do with the lack of a suitable syntax to
distinguish the partial specialization of the member function of the
primary template from the definition of a member of a partially
specialized class.



Anyway, there's pretty much a full workaround for this as you can see in
the following code.  The idea is that for instantiations of class A
where T is a pointer, a call to foo(int) will result in a call to
foo2(int)  e.g.  A<int*>().foo(2) calls foo2 as would A<T*>().foo(2) for
any T.

Graeme



#include <iostream>
#include <vector>
using std::vector;

template<class T>
class A
{
   template<class U> void a_foo( A<U>*, int k) { foo1(k); }
   template<class U> void a_foo( A<U*>*, int k ) { foo2(k); }
   void a_foo( A<vector<int> >*, int k) { foo3(k); }

   void foo1(int k) { std::cout << "\nfoo1 " << k; }
   void foo2(int k) { std::cout << "\nfoo2 " << k; }
   void foo3(int k) { std::cout << "\nfoo3 " << k; }
public:
   void foo(int k)  { a_foo(this,k); }
};

int main()
{
  A<int>().foo(1);
  A<int*>().foo(2);
  A<vector<int> >().foo(3);
}




---
[ 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: a9804814@unet.univie.ac.at (Thomas Mang)
Date: Mon, 5 Jan 2004 18:51:23 +0000 (UTC)
Raw View

Graeme Prentice schrieb:

>
> #include <iostream>
> #include <vector>

I don't want to be pedantic, but you are missing #include <ostream> here

>
> using std::vector;

>
>
> template<class T>
> class A
> {
>    template<class U> void a_foo( A<U>*, int k) { foo1(k); }
>    template<class U> void a_foo( A<U*>*, int k ) { foo2(k); }
>    void a_foo( A<vector<int> >*, int k) { foo3(k); }
>
>    void foo1(int k) { std::cout << "\nfoo1 " << k; }
>    void foo2(int k) { std::cout << "\nfoo2 " << k; }
>    void foo3(int k) { std::cout << "\nfoo3 " << k; }
> public:
>    void foo(int k)  { a_foo(this,k); }
> };
>
> int main()
> {
>   A<int>().foo(1);
>   A<int*>().foo(2);
>   A<vector<int> >().foo(3);
> }

regards,

Thomas

---
[ 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: stiss@gmx.net (SainTiss)
Date: Mon, 29 Dec 2003 00:14:04 +0000 (UTC)
Raw View
Hi,

I've been looking into the standard for a clear statement on whether partial
specialization of member functions of class templates is allowed or not.

14.7.3/4 says that explicit specialization of a member function is legal,
but doesn't state that partial specialization is not.

One might argue that the standard indicates that partial specialization
implies a distinct template, and therefore defining a member function
requires the specialized class to be defined as well (explicitly
instantiated).
However, I don't find that very clear in the standard...

Did I just misinterpret some sections, or is this really somewhat blurry?

Thanks,

Hans

---
[ 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: invalid@yahoo.co.nz (Graeme Prentice)
Date: Thu, 1 Jan 2004 08:35:10 +0000 (UTC)
Raw View

[ my apologies if this turns up twice.  I don't recall receiving an auto
acknowledgement and the post hasn't turned up so I'm reposting it.
Graeme ]


On Mon, 29 Dec 2003 00:14:04 +0000 (UTC), SainTiss wrote:

>Hi,
>
>I've been looking into the standard for a clear statement on whether partial
>specialization of member functions of class templates is allowed or not.
>
>14.7.3/4 says that explicit specialization of a member function is legal,
>but doesn't state that partial specialization is not.


All 21 paragraphs of 14.7.3 are devoted entirely to explicit
specialization (of various sorts).

>
>One might argue that the standard indicates that partial specialization
>implies a distinct template, and therefore defining a member function
>requires the specialized class to be defined as well (explicitly
>instantiated).
>However, I don't find that very clear in the standard...
>
>Did I just misinterpret some sections, or is this really somewhat blurry?

14.5.4 is devoted  entirely to class template partial specializations -
The title of
14.5.4.2 Partial ordering of class template specializations
could perhaps be
14.5.4.2 Partial ordering of class template partial specializations

and similarly 14.5.4.3.

The fact that the standard doesn't describe any means of "partially
specialising" a non template member function of a template class is
sufficient indication that it is not allowed.  However, it wouldn't hurt
for 14.5.1.1 (Member functions of class templates), to mention that non
template member functions of a template class can be explicitly
specialized (and refer to the example in para 16 of 14.7.3) and to also
mention that partial specialization of a non template member function of
a template class is not allowed.  Note, para 16 of 14.7.3 has been
corrected in TC1 (C++ 2003).

If you look at the example in 14.7.3 para 5, it shows how to define an
out of class member function of an explicitly specialized template class
- it looks like this
         void A<int>::f() { /* ... */ }

note there is no "template <>" prefix on this definition.  This
distinguishes it from an explicit specialization of a member of a
template class when there is no corresponding explicitly specialized
template class - as shown in 14.7.3 para 16
       template<> void A<int>::f(int);

For the case of partial specialization, if you take the example in
14.7.3 para 16
    template<class T> struct A {
          void f(T);
          template<class X> void g(T,X);
          void h(T) { }
       };

You could attempt to define a partial specialization of f() as e.g.

template <typename T1>
void A<T1*>::f(T1*) {}
as in 14.5.4.3 para 1, but this is not allowed.  I do not know if the
reason was anything to do with the lack of a suitable syntax to
distinguish the partial specialization of the member function of the
primary template from the definition of a member of a partially
specialized class.



Anyway, there's pretty much a full workaround for this as you can see in
the following code.  The idea is that for instantiations of class A
where T is a pointer, a call to foo(int) will result in a call to
foo2(int)  e.g.  A<int*>().foo(2) calls foo2 as would A<T*>().foo(2) for
any T.

Graeme



#include <iostream>
#include <vector>
using std::vector;

template<class T>
class A
{
   template<class U> void a_foo( A<U>*, int k) { foo1(k); }
   template<class U> void a_foo( A<U*>*, int k ) { foo2(k); }
   void a_foo( A<vector<int> >*, int k) { foo3(k); }

   void foo1(int k) { std::cout << "\nfoo1 " << k; }
   void foo2(int k) { std::cout << "\nfoo2 " << k; }
   void foo3(int k) { std::cout << "\nfoo3 " << k; }
public:
   void foo(int k)  { a_foo(this,k); }
};

int main()
{
  A<int>().foo(1);
  A<int*>().foo(2);
  A<vector<int> >().foo(3);
}



---
[ 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                       ]