How to specialize a template for a class hierarchy (non intrusive)

How to specialize a template for a class hierarchy (non intrusive)

Post by Joerg Richt » Sun, 27 Jul 2003 04:38:43



Hi,

I want to have something like this:

struct Base {};
struct Derived : Base {};

// 1
template<class T>
void func( T* t )
{}

// 2
template<>
void func( Base* t )
{}

int main()
{
   Base b;
   Derived d;
   func( &b );  // calls 1
   func( &d );  // calls also 1

Quote:}

but i want the second func to call 2.

I know that this is somehow possible with boost::is_base_and_derived.
But i have to modify the base template somehow to get this done. eg:

template<class T>
void func( T* t )
{
   real_func<boost::is_base_and_derived<Base,T>::value>( t );

Quote:}

So every time i add another class hierarchy i have to modify the base
template even more and add more and more dependencies to it.

Is it somehow possible to do this thing without touching the base
template?

Joerg

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

How to specialize a template for a class hierarchy (non intrusive)

Post by Daniel Spangenber » Tue, 29 Jul 2003 18:59:35


Hello, Joerg Richter!

Joerg Richter schrieb:
[snip]

 > I know that this is somehow possible with boost::is_base_and_derived.
 > But i have to modify the base template somehow to get this done. eg:
 >
 > template<class T>
 > void func( T* t )
 > {
 >    real_func<boost::is_base_and_derived<Base,T>::value>( t );
 > }
 >
 > So every time i add another class hierarchy i have to modify the base
 > template even more and add more and more dependencies to it.
 >
 > Is it somehow possible to do this thing without touching the base
 > template?
 >
 > Joerg

I think, it is a quite good idea to provide only the generic function
template,
which dispatches its call via either a full function template
spezialization or
by full or partial class template specialization. My preference for the
last
option is due to the fact, that you can always fake a partial function
template
specialization by this and you don't need the usual tag-technique for
selecting
the correct algorithm.

In cases like this, one further level of indirection usually helps.
Instead of

template<class T>
void func( T* t )
{
    real_func<boost::is_base_and_derived<Base,T>::value>( t );

Quote:}

I propose to invent a class, which returns the compile-time value true
for
all cases, where you want your specialized function call, like

template <typename T>
struct SpecialTreatment { // This is the place, where you add your
further
   // class heirachies and the complete decision logic
   enum { value = boost::is_base_and_derived<Base,T>::value ||
      boost::is_base_and_derived<Base2,T>::value  // Whatever special
class or conditions you like
     };

Quote:};

and modify your general function template for once and only once to

template<class T>
void func( T* t )
{
    real_func<SpecialTreatment<T>::value>( t );

Quote:}

Hope that helps,

Daniel Spangenberg

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

How to specialize a template for a class hierarchy (non intrusive)

Post by Joerg Richt » Wed, 30 Jul 2003 06:47:03


first one correction

Quote:> int main()
> {
>    Base b;
>    Derived d;
>    func( &b );  // calls 1

should mean "calls 2"

But i found now a solution that works for me. Perhaps you can comment
on it.

struct Base {};
struct Derived : Base {};
struct Foo {};

// 1
template<class T>
void funcHelper( T* t, void* )
{}

// 2
template<class T>
void funcHelper( T* t, Base* )
{}

template<class T>
void func( T* t )
{
  funcHelper( t, t );

Quote:}

int main()
{
   Base b;
   Derived d;
   Foo f;

   func( &b );  // calls 2
   func( &d );  // calls 2
   func( &f );  // calls 1

Quote:}

This works because of the additional dummy argument. The first
parameter matches always exact while the second matches better for
Base objects or all derived classes.

Now you can add additional class hierarchies without modifying the
general template (1).

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

 
 
 

1. Simple question (Specialized templates within non-specialized templates)

Hi all you C++ gurus,

Consider this small example:

template<typename T, int I> class A {} ;

class B {};   // no templates
class C {};

 I have an explicitly specialized function that returns different
stuff based on what is the template parameter:

template <typename T> func();
template<> int func<B>();
template<> int func<C>();

Now I want this function to serve the A. BUT

template<typename T, int I>
template<> function<A<T,I> > func() {};

is illegal, because the standard prohibits specialization of a
template within a NON-specialized template.

Any workarounds?

Thanks!!


      [ about comp.lang.c++.moderated. First time posters: do this! ]

2. Adaptec scsi raid s3200

3. intrusive vs non-intrusive reference counting

4. PB3.0+Sybase: stored procedures

5. Intrusive v. Non-intrusive containers

6. MKDIR commands in a batch file

7. Can you specialize a Template class by specifying only the member function that should be specialized?

8. Microcosm, Chaos Engine and other compilation??

9. Specializing template class members (not class member templates)

10. Q: How to provide a partially specialized template inside a template class?

11. Q: Specializing member templates of template classes

12. How to make a general template class friend of a non-template class?

13. How to nest a non-template class in a template class ?