Recover template type from non-template base class

  • Thread starter michael.alexeev
  • Start date
M

michael.alexeev

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
 
A

amparikh

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>
{
};
 
A

amparikh

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>
{
};
 
M

michael.alexeev

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
 
A

amparikh

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top