Thread: Template specialisation for templated base class

  1. #1
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597

    Template specialisation for templated base class

    Hi all,
    I have a template that I want to specialise for a specific class and it's sub classes i.e.
    Code:
    template <typename T>
    class MyTemplate
    {
    public:
        static void DoStuff(void)
        {
             cout << "generic template" << endl;
        }
    };
    
    class Base
    {
    };
    
    class Derived : public Base
    {
    };
    
    template <>
    class MyTemplate<Base>
    {
    public:
        static void DoStuff(void)
        {
             cout << "base template" << endl;
        }
    };
    
    int main()
    {
    	MyTemplate<int>::DoStuff();        // OK - prints "generic template"
    	MyTemplate<Base>::DoStuff();    // OK - prints "base template"
    
    	MyTemplate<Derived>::DoStuff(); // BAH! - prints "generic template" 
    }
    anyone have any ideas? If I can solve this than I'll worry about the next problem (Base is also a template!!)
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    	MyTemplate<int>::DoStuff();        // OK - prints "generic template"
    	MyTemplate<Base>::DoStuff();    // OK - prints "base template"
    
    	MyTemplate<Derived>::DoStuff(); // BAH! - prints "generic template"
    you have not specialized the template for Derived so it uses the generic function.
    Kurt

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Boost's enable_if plus is_base_and_derived from Boost.Type_Traits can sort of accomplish what you want. But it's not as simple as just specializing the class.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by ZuK
    Code:
    	MyTemplate<int>::DoStuff();        // OK - prints "generic template"
    	MyTemplate<Base>::DoStuff();    // OK - prints "base template"
    
    	MyTemplate<Derived>::DoStuff(); // BAH! - prints "generic template"
    you have not specialized the template for Derived so it uses the generic function.
    Kurt
    I know WHY it doesn't work! I'm trying to find a way around it!

    CornedBee, I thought about is_base_of but couldn't figure out a way to get it to work, but enable_if looks promising. I'll give it a shot, cheers!
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Sorry. I should read your posts more carefully. Didn't see the "and it's sub classes"
    Kurt

  6. #6
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    ok I tried CornedBee's idea and it works!
    Code:
    #include <boost/type_traits.hpp>
    #include <boost/utility.hpp>
    #include <boost/mpl/or.hpp>
    
    template <typename T, typename Enable = void>
    class MyTemplate
    {
    public:
        static void DoStuff(void)
        {
             cout << "generic template" << endl;
        }
    };
    
    class Base
    {
    };
    
    class Derived : public Base
    {
    };
    
    template <typename T>
    class MyTemplate<T, 
    					  typename boost::enable_if<
    							boost::mpl::or_<
    								boost::is_base_of<Base, T>,
    								boost::is_same<Base, T>
    							>
    						>::type>
    {
    public:
        static void DoStuff(void)
        {
             cout << "base template" << endl;
        }
    };
    
    int main()
    {
    	MyTemplate<int>::DoStuff();        // OK - prints "generic template"
    	MyTemplate<Base>::DoStuff();    // OK - prints "base template"
    
    	MyTemplate<Derived>::DoStuff(); // Woohoo! - prints "base template" 
    }
    god, I love boost! now I just need to figure out how to make it work with a templated Base class...
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  7. #7
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    havent worked with this type of stuff in a while, but would 'virtual' help at all here?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, doesn't have anything to do with the issue.


    ChaosEngine, what exactly do you mean by templated base class? That there is a template parameter which names the type on which special handling is taken? I think you'll need a metafunction for that.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by CornedBee
    No, doesn't have anything to do with the issue.


    ChaosEngine, what exactly do you mean by templated base class? That there is a template parameter which names the type on which special handling is taken?
    not quite. It's a bit of an abuse of the type system really.

    if we have a class hierarchy like this
    Code:
    template <typename T>
    class Base
    {
    };
    
    class D1 : public Base<short>
    {
    };
    
    class D2 : public Base<int>
    {
    };
    D1 and D2 have no inheritance relationship as Base<int> and Base<short> are essentially 2 different classes. I've actually soved it using a private "grandfather" class
    Code:
    template <typename T, typename U = void, typename Enable = void>
    class MyTemplate
    {
    public:
        static void DoStuff(void)
        {
    		 cout << "generic template: " << typeid(T).name() << endl;
        }
    };
    
    
    class BaseBase {};
    
    template <typename T>
    class Base : private BaseBase
    {
    };
    
    class Derived : public Base<short>
    {
    };
    
    class D2 : public Base<int>
    {
    };
    
    template <typename T>
    class MyTemplate<T,
                                  typename boost::enable_if<boost::is_base_of<BaseBase, T> >::type
                                 >
    {
    public:
        static void DoStuff(void)
        {
    		 cout << "base template: " << typeid(T).name() << endl;
        }
    };
    
    int main()
    {
    	MyTemplate<int>::DoStuff();     // OK - prints "generic template"
    	MyTemplate<Base<int> >::DoStuff();    // OK - prints "base template"
    
    	MyTemplate<Derived>::DoStuff(); // Woohoo! - prints "base template" 
    	MyTemplate<D2>::DoStuff(); // Woohoo! - prints "base template" 
    }
    it's a bit of a hack, but it works.

    all this work is actually to define a metafunction to handle specialised Scalar math, but it works now. Thanks everyone, especially CornedBee.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Weird errors.
    By Desolation in forum C++ Programming
    Replies: 20
    Last Post: 05-09-2007, 01:10 PM
  2. help with template class using a template node
    By aciarlillo in forum C++ Programming
    Replies: 11
    Last Post: 06-02-2005, 05:46 PM
  3. Operator overloading in template classes
    By moejams in forum C++ Programming
    Replies: 5
    Last Post: 07-21-2003, 05:16 PM
  4. Replies: 4
    Last Post: 12-29-2002, 12:29 AM
  5. Virtual Base Class & Constructor :: C++
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 09-13-2002, 03:14 PM