Thread: Dynamic Inheritence using Templates

  1. #1
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195

    Dynamic Inheritence using Templates

    Can someone please tell me if this sort of thing is possible:

    I have three classes, A, B, C. and I have a fourth, class D, that inherits any one of A, B or C. Is it possible to dynamically pick which one to inherit from without using the strategy (or bridge) patterns:

    For example:

    Code:
    template <class T = someCondition ? A : B> class D;
    
    class C {...};
    class B {...};
    class A {...};
    
    template <class T>
    class D : public T
    {
    ...
    };
    Then later, dynamically have the base class chosen for me by setting what the someCondition variable is set to.

    Code:
    A<> i;
    Is this sort of thing possible? Or is there a better way of auto-picking the base class of a template WITHOUT manually specifying the template parameters?
    Founder and avid member of the Internationsl Typo Associateion

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Do you have any concrete examples for the four classes? It does sound like a design pattern will be appropriate instead of trying some C++ template magic.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You can't do anything dynamic with templates, but with compile time constants what you said could be made to work.

    What are you trying to do specifically?
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Here's a use case. Suppose you have a compile-time-sized buffer class:
    Code:
    template <typename E, size_t Size>
    class buffer;
    Suppose further you want this buffer to be in the class if it is smaller than some threshold, but dynamically allocated if it's larger. (That's because the primary use for the buffer is to be on the stack, but space is limited.)
    Code:
    const size_t THRESHOLD = 1024 * 16; // 16k
    Here's one way to do it at zero runtime cost.
    Code:
    #include <stddef>
    
    #include <boost/scoped_array.hpp>
    #include <boost/mpl/if.hpp>
    
    using std::size_t;
    
    namespace detail
    {
      template <typename E, size_t Size>
      class direct_holder
      {
        E m_data[Size];
      public:
        E *ptr() { return m_data; }
        E const *ptr() const { return m_data; }
      };
    
      template <typename E, size_t Size>
      class heap_holder
      {
        boost::scoped_array<E> m_data;
      public:
        heap_holder() : m_data(new E[Size]) {}
        E *ptr() { return m_data.get(); }
        E const *ptr() const { return m_data.get(); }
      };
    }
    
    template <typename E, size_t Size>
    class buffer :
      private boost::mpl::if_c<
        Size < THRESHOLD,
        direct_holder<E, Size>,
        heap_holder<E, Size>
      >::type
    {
      // Don't forget to use this->ptr()
    };

    Of course, if memory serves, that's exactly the strategy pattern, but with automatic strategy selection.
    Last edited by CornedBee; 10-24-2007 at 04:07 AM.
    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

  5. #5
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Very interesting. My concrete example is using a few specialized classes for SIMD. Some are SSE, 3DNow, etc.

    The only reason why I did not use a straight up stategy pattern was because of the extra overhead. I'm aiming for the shortest path possible so that its really fast. But if there is no way around it, This boost method might be nice.

    Thanks.
    Founder and avid member of the Internationsl Typo Associateion

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    There ought to be no runtime overhead in the template strategy pattern.

    By the way, if you don't want all of Boost just for mpl::if_c, here's a simple implementation. It doesn't have all the workarounds for broken compilers that mpl::if_c has, tough. It will not, for example, work on VC++6.
    Code:
    template <bool Cond, typename ThenType, typename ElseType>
    struct if_c { typedef ElseType type; };
    
    template <typename ThenType, typename ElseType>
    struct if_c<true, ThenType, ElseType> { typedef ThenType type; };
    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

  7. #7
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    That works fine and dandy if I manualy hard code the template Type. If I try to dynamically input a bool into Cond, it doesnt compile:

    Code:
    bool a = false;
    
    // This doenst compile
    if_c<a, classOne, classTwo> i;
    Founder and avid member of the Internationsl Typo Associateion

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That's because templates are a compile time mechanism. You can't use them to solve runtime problems. (You can use them to refactor runtime problems, but that's a whole different can of worms.)
    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
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    Dang, there goes my hope for on the fly dynamic inheritance.
    O well.
    Founder and avid member of the Internationsl Typo Associateion

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Surely, what you want is something like this:
    Code:
    class Base {
       ...
    public:
       virtual calculatesomething() = 0;
       ....
    };
    
    
    class CSSE : public Base 
    {
       virtual calculatesomething();
    }
    
    CSSE::calculatesomething() {
      ... SSE code ...
    }
    
    class C3DNow: public Base
    {
       virtual calculatesomething();
    }
    
    C3DNow::calculatesomething() {
      ... 3DNow code ...
    }
    
    
    class CGeneric: public Base
    {
       virtual calculatesomething();
    }
    
    CGeneric::calculatesomething()
    {
        .... Use standard C library to perform the math ... 
    }
    
    Base *pClass;
    
    int main()
    {
        int x;
        x = bestMath();
        switch(x)
        {
           case M_SSE:
              pClass = new CSSE;
              break;
           case M_3DNow:
              pClass = new CSSE;
              break;
           default:
              pClass = new CGeneric;
         }
         pClass->calculateSomething;
    }
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Codebot
    Join Date
    Jun 2004
    Location
    Toronto
    Posts
    195
    matsp, Yes Thats what I am going to implement now. Or at least something similar.
    Thanks for the insight tho.
    Founder and avid member of the Internationsl Typo Associateion

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Identify dynamic IP address of network device
    By BobS0327 in forum Tech Board
    Replies: 2
    Last Post: 02-21-2006, 01:49 PM
  2. Questions about Templates
    By Shamino in forum C++ Programming
    Replies: 4
    Last Post: 12-18-2005, 12:22 AM
  3. When and when not to use templates
    By *ClownPimp* in forum C++ Programming
    Replies: 7
    Last Post: 07-20-2003, 09:36 AM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM