Topic: Recursive partial specialization?


Author: Biju Thomas <b_thomas@ibm.net>
Date: 1999/06/09
Raw View
Hello,

I have the following code:

 // Primary template
 template < class T > class Foo {
   // all members
 };
 // Partial specialization for pointers
 template < class T > class Foo<T*> {
   Foo<void*> m_Impl;
   // Provide the members of Foo in terms of m_Impl
 };

My compiler complains about recursive template definitions, saying that
Foo<void*> is implemented in terms of Foo<void*>.

Is my compiler right? (References to the standard will be appreciated.)

If so, does it mean that if I want to provide a partial specialization
for Foo<T*>, I have to implement a complete specialization for
Foo<void*>? That is sort of like duplicating the entire code for the
primary template in the complete specialization for Foo<void*>.

Thanks,

Biju 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "anatoli" <anatoli@ptc.-DOT-.com>
Date: 1999/06/10
Raw View
On 09 Jun 99 20:01:20 GMT Biju Thomas <b_thomas@ibm.net> wrote:
> Hello,
>
> I have the following code:
>
>  // Primary template
>  template < class T > class Foo {
>    // all members
>  };
>  // Partial specialization for pointers
>  template < class T > class Foo<T*> {
>    Foo<void*> m_Impl;
>    // Provide the members of Foo in terms of m_Impl
>  };
>
> My compiler complains about recursive template definitions, saying that
> Foo<void*> is implemented in terms of Foo<void*>.
>
> Is my compiler right? (References to the standard will be appreciated.)

I *think* your compiler is right.  No refs to the standard,
sorry.  But try to follow the compiler's logic and you'll see
it's hard to do any better.

>
> If so, does it mean that if I want to provide a partial specialization
> for Foo<T*>, I have to implement a complete specialization for
> Foo<void*>? That is sort of like duplicating the entire code for the
> primary template in the complete specialization for Foo<void*>.

You can do this:

// Primary template
template < class T, bool isSpec = false > class Foo {
  // all members
};
// Partial specialization for pointers
template < class T > class Foo<T*, false> {
  Foo<void*, true> m_Impl;
  // Provide the members of Foo in terms of m_Impl
};

--
Anatoli Tubman
anatoli <at> ptc <dot> com -- opinions aren't
--
Posted via Talkway - http://www.talkway.com
Exchange ideas on practically anything (tm).



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/10
Raw View
Biju Thomas wrote:
>
> Hello,
>
> I have the following code:
>
>  // Primary template
>  template < class T > class Foo {
>    // all members
>  };
>  // Partial specialization for pointers
>  template < class T > class Foo<T*> {
>    Foo<void*> m_Impl;
>    // Provide the members of Foo in terms of m_Impl
>  };
>
> My compiler complains about recursive template definitions, saying that
> Foo<void*> is implemented in terms of Foo<void*>.
>
> Is my compiler right? (References to the standard will be appreciated.)

It's a logical necessity; there's no need to find the relevant section
of the standard. Foo<T*>::member() calls Foo<void*>::member(); if you're
not to produce an infinitly recursive set of function calls, somewhere
along the line you have to define what member() actually does, instead
of calling another function.

> If so, does it mean that if I want to provide a partial specialization
> for Foo<T*>, I have to implement a complete specialization for
> Foo<void*>?

Yes.

> ... That is sort of like duplicating the entire code for the
> primary template in the complete specialization for Foo<void*>.

You'd better not duplicate the entire primary template in the
specialization; in that case every Foo<void*> would contain another
Foo<void*>, each of which must be at least 1 byte in size, even if it
has no other non-static data members, making it infinitely large.

What you're doing is analogous to saying that f(n)=f(0)+n; that's a
perfectly reasonable definition, but it's not complete - you have to
define what f(0) is.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jens Kilian <Jens_Kilian@bbn.hp.com>
Date: 1999/06/10
Raw View
"anatoli" <anatoli@ptc.-DOT-.com> writes:
> On 09 Jun 99 20:01:20 GMT Biju Thomas <b_thomas@ibm.net> wrote:
> > Hello,
> >
> > I have the following code:
> >
> >  // Primary template
> >  template < class T > class Foo {
> >    // all members
> >  };
> >  // Partial specialization for pointers
> >  template < class T > class Foo<T*> {
> >    Foo<void*> m_Impl;
> >    // Provide the members of Foo in terms of m_Impl
> >  };
> >
> > My compiler complains about recursive template definitions, saying that
> > Foo<void*> is implemented in terms of Foo<void*>.

[...]

> You can do this:
>
> // Primary template
> template < class T, bool isSpec = false > class Foo {
>   // all members
> };
> // Partial specialization for pointers
> template < class T > class Foo<T*, false> {
>   Foo<void*, true> m_Impl;
>   // Provide the members of Foo in terms of m_Impl
> };

No need to get nasty - just add an explicit instantiation for Foo<void*>:

     // Primary template
     template < class T > class Foo {
       // all members
     };

     // Explicit instantiation for void*.
     template class Foo<void*>;

     // Partial specialization for all other pointers
     template < class T > class Foo<T*> {
       Foo<void*> m_Impl;
       // Provide the members of Foo in terms of m_Impl
     };

HTH,
 Jens.
--
mailto:jjk@acm.org                 phone:+49-7031-14-7698 (HP TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-14-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]