Recover template type from non-template base class

Discussion in 'C++' started by michael.alexeev@qwest.com, Jun 1, 2006.

  1. Guest

    Hi all.

    Consider the following code fragment:

    #include <string>
    struct Base{ virtual ~Base() {} };
    template <typename T> struct Derived : public Base {};

    Base* Create (int param) {
    switch (param) {
    case 1:
    return new Derived<int>;
    case 2:
    return new Derived<std::string>;
    }
    }

    void foo(Derived<int>*);
    void foo(Derived<std::string>*);


    Ideally, I would like to write something like this:

    int main() {
    Base* base = Create(1);
    foo(base);
    }

    I tried to add downcast method to Base:

    template <typename T>
    struct Derived;
    struct Base{
    virtual ~Base() {}
    template <typename T>
    Derived<T> * downcast(){
    Derived<T>* d = static_cast<Derived<T>*>(this);
    if (d == 0) throw;
    return d;
    }
    }

    But it does not help since I still need to specify Derived type during
    foo call:
    foo(base->downcast<int>);

    which I want to avoid.

    Any idea how to do it?

    Thanks,
    Mike Alexeev
     
    , Jun 1, 2006
    #1
    1. Advertising

  2. Guest

    wrote:
    > Hi all.
    >
    > Consider the following code fragment:
    >
    > #include <string>
    > struct Base{ virtual ~Base() {} };
    > template <typename T> struct Derived : public Base {};
    >
    > Base* Create (int param) {
    > switch (param) {
    > case 1:
    > return new Derived<int>;
    > case 2:
    > return new Derived<std::string>;
    > }
    > }
    >
    > void foo(Derived<int>*);
    > void foo(Derived<std::string>*);
    >
    >
    > Ideally, I would like to write something like this:
    >
    > int main() {
    > Base* base = Create(1);
    > foo(base);
    > }
    >
    > I tried to add downcast method to Base:
    >
    > template <typename T>
    > struct Derived;
    > struct Base{
    > virtual ~Base() {}
    > template <typename T>
    > Derived<T> * downcast(){
    > Derived<T>* d = static_cast<Derived<T>*>(this);
    > if (d == 0) throw;
    > return d;
    > }
    > }
    >
    > But it does not help since I still need to specify Derived type during
    > foo call:
    > foo(base->downcast<int>);
    >
    > which I want to avoid.
    >
    > Any idea how to do it?
    >
    > Thanks,
    > Mike Alexeev


    What you need is a CRTP. do google on " Curiously recurring template
    pattern".

    template <class Derived>
    struct base
    {
    Derived* downcast()
    {
    return static_cast<Derived*>(this);
    }
    };

    struct derived : base<derived>
    {
    };
     
    , Jun 1, 2006
    #2
    1. Advertising

  3. Guest

    wrote:
    > Hi all.
    >
    > Consider the following code fragment:
    >
    > #include <string>
    > struct Base{ virtual ~Base() {} };
    > template <typename T> struct Derived : public Base {};
    >
    > Base* Create (int param) {
    > switch (param) {
    > case 1:
    > return new Derived<int>;
    > case 2:
    > return new Derived<std::string>;
    > }
    > }
    >
    > void foo(Derived<int>*);
    > void foo(Derived<std::string>*);
    >
    >
    > Ideally, I would like to write something like this:
    >
    > int main() {
    > Base* base = Create(1);
    > foo(base);
    > }
    >
    > I tried to add downcast method to Base:
    >
    > template <typename T>
    > struct Derived;
    > struct Base{
    > virtual ~Base() {}
    > template <typename T>
    > Derived<T> * downcast(){
    > Derived<T>* d = static_cast<Derived<T>*>(this);
    > if (d == 0) throw;
    > return d;
    > }
    > }
    >
    > But it does not help since I still need to specify Derived type during
    > foo call:
    > foo(base->downcast<int>);
    >
    > which I want to avoid.
    >
    > Any idea how to do it?
    >
    > Thanks,
    > Mike Alexeev


    What you need is a CRTP. do google on " Curiously recurring template
    pattern".

    template <class Derived>
    struct base
    {
    Derived* downcast()
    {
    return static_cast<Derived*>(this);
    }
    };

    struct derived : base<derived>
    {
    };
     
    , Jun 1, 2006
    #3
  4. Guest

    wrote:
    > What you need is a CRTP. do google on " Curiously recurring template
    > pattern".
    >
    > template <class Derived>
    > struct base


    Unfortunately, Base class can't be a template class. It could only have
    template methods.

    Thanks,
    Mike
     
    , Jun 1, 2006
    #4
  5. Guest

    wrote:
    > wrote:
    > > What you need is a CRTP. do google on " Curiously recurring template
    > > pattern".
    > >
    > > template <class Derived>
    > > struct base

    >
    > Unfortunately, Base class can't be a template class. It could only have
    > template methods.
    >
    > Thanks,
    > Mike


    the following works for me.

    template<typename T>
    struct derived;

    struct base
    {
    template<typename T>
    derived<T>* downcast()
    {
    return static_cast<derived<T>*>(this);
    }

    };

    template <class T>
    struct derived : base
    {
    void func()
    {
    cout << " derived::foo" << endl;
    }
    };

    template<typename T>
    void foo(derived<T>* d)
    {
    d->func();
    }

    You could also use a conversion operator if you want instead of a
    downcast function.
     
    , Jun 1, 2006
    #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. Matt Graham
    Replies:
    0
    Views:
    568
    Matt Graham
    Jul 21, 2003
  2. Replies:
    2
    Views:
    570
  3. nguillot
    Replies:
    5
    Views:
    539
  4. Hicham Mouline
    Replies:
    1
    Views:
    603
    Victor Bazarov
    Apr 20, 2009
  5. Ariel Gimenez

    recover value from datagrid w/template columns

    Ariel Gimenez, Apr 16, 2004, in forum: ASP .Net Datagrid Control
    Replies:
    2
    Views:
    114
    Ariel Gimenez
    Apr 19, 2004
Loading...

Share This Page