Dynamic polymorphism and subclass template parameters?

Discussion in 'C++' started by none, Mar 6, 2010.

  1. none

    none Guest

    I am trying to do the following (ASub and BSub are subclasses of A and B):


    typedef A AType;
    typedef B BType;
    typedef ASub ASubType;
    typedef BSub BSubType;

    typedef SimpleBase<AType, BType> JobBaseType;
    typedef Simple<ASubType, BSubType> JobSimpleType;
    typedef std::vector<JobBaseType*> JobContainerType;


    JobContainerType jobs;


    // Works Fine!
    JobBaseType * baseJob = new JobBaseType;
    baseJob->name();


    // ERROR!!
    JobBaseType * simpleJob = new JobSimpleType;
    simpleJob->name();





    But the last initialization gives this error:


    error: cannot convert ‘main()::JobSimpleType*’ to ‘main()::JobBaseType*’ in initialization

    The problem is:

    typedef Simple<ASubType, BSubType> JobSimpleType;

    If I change this to:

    typedef Simple<AType, BType> JobSimpleType;

    it works.


    Is there no way to create a pointer to a basetype<A,B> from a subtype<ASub, BSub> with subtype
    template parameters, like:


    JobBaseType * simpleJob = new JobSimpleType;

    ?
     
    none, Mar 6, 2010
    #1
    1. Advertising

  2. On Mar 7, 2:32 am, none <""mort\"@(none)"> wrote:
    > I am trying to do the following (ASub and BSub are subclasses of A and B):
    >
    > ...
    >
    >    typedef SimpleBase<AType, BType>                  JobBaseType;
    >    typedef Simple<ASubType, BSubType>                JobSimpleType;
    > ...


    SimpleBase<> and Simple<> are not part of the C++ Standard... unless
    you show the code, how is anyone supposed to help you?

    Cheers,
    Tony
     
    Anthony Delroy, Mar 8, 2010
    #2
    1. Advertising

  3. none

    Robert Fendt Guest

    And thus spake none <""mort\"@(none)">
    Sat, 06 Mar 2010 18:32:56 +0100:

    > The problem is:
    >
    > typedef Simple<ASubType, BSubType> JobSimpleType;
    >
    > If I change this to:
    >
    > typedef Simple<AType, BType> JobSimpleType;
    >
    > it works.


    Since you do not show the template definitions, I am wildly
    guessing here. Thus I can give only a very general answer.

    A class template is just that: a template. There is no
    polymorphic relation between template instantiations with
    different parameters, thus they are distinct types. I.e.,
    std::vector<int> is something quite different to
    std::vector<double>. Thus, if you are trying to do something
    like this:

    template <typename T>
    class base
    {
    virtual void foo() = 0;
    };

    template <typename T>
    class deriv : public base<T>
    {
    virtual void foo() {}
    }

    then you will not be able to convert a deriv<Type1_t> to a
    deriv<Type2_t>, since each of them creates 'its own' special
    base-class from the base template. In other words, there cannot
    be any dynamic polymorphism between the two. Inheritance in this
    fashion still can have its uses. E.g. in combination with
    partical specialisation techniques it can help avoid code
    duplication, or the base can be instantiated directly with the
    derived type ('curiously recurring template pattern'). But it
    just will not work the way you probably intend it to.

    What you have to do is base all your derived class templates
    upon a non-templated class. I.e., this should work:

    class base2
    {
    virtual void foo() = 0;
    };

    template <typename T>
    class deriv2 : public base2
    {
    virtual void foo() {}
    };

    You can also use a templated base, but you will have to base all
    derived templates on the same instantiation (i.e., one not
    depending on the current template parameters). In other words,
    this should be fine too:

    template <typename T>
    class deriv3 : public base<int>
    {
    virtual void foo() {}
    };


    Regards,
    Robert
     
    Robert Fendt, Mar 8, 2010
    #3
  4. none

    Robert Fendt Guest

    And thus spake Robert Fendt <>
    Mon, 8 Mar 2010 07:30:42 +0100:

    > then you will not be able to convert a deriv<Type1_t> to a
    > deriv<Type2_t>, since each of them creates 'its own' special
    > base-class from the base template. In other words, there cannot
    > be any dynamic polymorphism between the two. Inheritance in this


    Small correction: this should of course be: one cannot convert a
    deriv<Type1_t> to a base<Type2_t> if it is not exactly based upon
    that type. In your code deriv<Type1_t> will probably be based
    upon base<Type1_t>, thus you have two different base classes.

    I just should not look at C++ problems at 7:00 in the morning...

    Regards,
    Robert
     
    Robert Fendt, Mar 8, 2010
    #4
  5. On 6 mar, 18:32, none <""mort\"@(none)"> wrote:
    > I am trying to do the following (ASub and BSub are subclasses of A and B):
    >
    >    typedef A                                         AType;
    >    typedef B                                         BType;
    >    typedef ASub                                      ASubType;
    >    typedef BSub                                      BSubType;
    >
    >    typedef SimpleBase<AType, BType>                  JobBaseType;
    >    typedef Simple<ASubType, BSubType>                JobSimpleType;
    >    typedef std::vector<JobBaseType*>                 JobContainerType;
    >
    >    JobContainerType jobs;
    >
    >    // Works Fine!
    >    JobBaseType * baseJob = new JobBaseType;
    >    baseJob->name();
    >
    >    // ERROR!!
    >    JobBaseType * simpleJob = new JobSimpleType;
    >    simpleJob->name();
    >
    > But the last initialization gives this error:
    >
    >   error: cannot convert main()::JobSimpleType* to main()::JobBaseType* in initialization
    >
    > The problem is:
    >
    >    typedef Simple<ASubType, BSubType>                JobSimpleType;
    >
    > If I change this to:
    >
    >    typedef Simple<AType, BType>                JobSimpleType;
    >
    > it works.
    >
    > Is there no way to create a pointer to a basetype<A,B> from a subtype<ASub, BSub> with subtype
    > template parameters, like:
    >
    >    JobBaseType * simpleJob = new JobSimpleType;
    >
    > ?


    Simple<ASubType, BSubType> must inherit from SimpleBase<AType, BType>.

    You can either (1) pass additional parameters to Simple<> or (2)deduce
    the bases from Asub and BSub or (3)you can do both:

    (1)
    template<class X, class Y, class Base>
    class Simple: public Base
    {
    // ...
    };

    template<class X, class Y, class XBase, class YBase>
    class Simple: public SimpleBase<XBase,YBase>
    {
    //...
    };

    (2)
    template<class X, class Y>
    class Simple: public SimpleBase<typename X::Base,typename Y::Base>
    {
    //...
    };

    (3)
    template<class X, class Y, class Base = SimpleBase<typename
    X::Base,typename Y::Base> >
    class Simple: public Base
    {
    // ...
    };

    // or any combination of the above

    --
    Michael
     
    Michael Doubez, Mar 8, 2010
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jstorta
    Replies:
    3
    Views:
    475
    jstorta
    Feb 20, 2006
  2. Krivenok Dmitry
    Replies:
    13
    Views:
    1,495
    Axter
    Jun 1, 2006
  3. Renato Golin

    polymorphism on template parameters

    Renato Golin, Aug 5, 2008, in forum: C++
    Replies:
    8
    Views:
    297
    Joe Greer
    Aug 5, 2008
  4. kito
    Replies:
    2
    Views:
    439
  5. S.Volkov
    Replies:
    2
    Views:
    242
    S.Volkov
    Mar 12, 2006
Loading...

Share This Page