type checking

C

Christof Warlich

Hi,

is there a way in C++ to check whether a class is derived from
a specific class? Initially, I tried to solve this problem through
template specialization, e.g.:

#include <iostream>
class Base {
};
template<typename T> class A {
public:
void f() {std::cout << "T is not a Base\n";}
};
template<> class A<Base> {
public:
void f() {std::cout << "T is a Base\n";}
};
class Derived: public Base {
};
class Any {
};
int main() {
A<Any> a1;
a1.f();
A<Derived> a2;
a2.f();
A<Base> a3;
a3.f();
}

Output:
T is not a Base
T is not a Base
T is a Base

As to be expected, Derived will be identified as not being a Base. Is
there any way to specialize a template for a complete class hierarchy
instead of just specific types? Any other ideas to execute different
code depending on whether the type being passed to a template is derived
from a certain base or not?

Thanks for any help,

Christof
 
V

Victor Bazarov

Christof said:
is there a way in C++ to check whether a class is derived from
a specific class?

Yes, sort of. Google for "is_derived C++ template". IIRC, Boost
has a way to do that.

The main question to ask yourself is, "Why do I need to do that?",
and then, "Is there a better way to do what I need without that?"
Initially, I tried to solve this problem through
template specialization, e.g.:

#include <iostream>
class Base {
};
template<typename T> class A {
public:
void f() {std::cout << "T is not a Base\n";}
};
template<> class A<Base> {
public:
void f() {std::cout << "T is a Base\n";}
};
class Derived: public Base {
};
class Any {
};
int main() {
A<Any> a1;
a1.f();
A<Derived> a2;
a2.f();
A<Base> a3;
a3.f();
}

Output:
T is not a Base
T is not a Base
T is a Base

As to be expected, Derived will be identified as not being a Base. Is
there any way to specialize a template for a complete class hierarchy
instead of just specific types? Any other ideas to execute different
code depending on whether the type being passed to a template is
derived from a certain base or not?

What are you trying to accomplish? Or is it just an academic exercise?

V
 
D

DDD

Hi,

is there a way in C++ to check whether a class is derived from
a specific class? Initially, I tried to solve this problem through
template specialization, e.g.:

#include <iostream>
class Base {};

template<typename T> class A {
public:
void f() {std::cout << "T is not a Base\n";}};

template<> class A<Base> {
public:
void f() {std::cout << "T is a Base\n";}};

class Derived: public Base {};
class Any {
};

int main() {
A<Any> a1;
a1.f();
A<Derived> a2;
a2.f();
A<Base> a3;
a3.f();

}

Output:
T is not a Base
T is not a Base
T is a Base

As to be expected, Derived will be identified as not being a Base. Is
there any way to specialize a template for a complete class hierarchy
instead of just specific types? Any other ideas to execute different
code depending on whether the type being passed to a template is derived
from a certain base or not?

Thanks for any help,

Christof

This problem is about Runtime Type Identification.
The following codes are refered from ANSI/ISO C++ Professional
Programmer's Handbook - Chapter 7

Operator typeid takes either an object or a type name as its argument
and returns a matching const type_info object.
The dynamic type of an object can be examined as follows:
OnRightClick (File & file)
{
if ( typeid( file) == typeid( TextFile ) )
{
//received a TextFile object; printing should be enabled
}
else
{
//not a TextFile object, printing disabled
}
}
 
C

Christof Warlich

Victor said:
Yes, sort of. Google for "is_derived C++ template". IIRC, Boost
has a way to do that.
Thanks a lot for the hint. This seems to do the trick:

#include <boost/type_traits/is_base_and_derived.hpp>
#include <iostream>

class Base {};
class Derived: public Base {};
class Any {};

int main() {
std::cout << boost::is_base_and_derived<Base, Derived>::value
<< boost::is_base_and_derived<Base, Any>::value
<< boost::is_base_and_derived<Derived, Any>::value
<< std::endl;
}

It prints 100 as desired.
The main question to ask yourself is, "Why do I need to do that?",
and then, "Is there a better way to do what I need without that?"

What are you trying to accomplish? Or is it just an academic exercise?
Well, it probably _is_ academic, as it just affects the performance of
an embedded system by being able to conditionally avoid a call of a
virtual member function. But as the system is close to its limits and
I like to dig a bit into template metaprogramming anyway, this may have
been a good real life starting point.
 
C

Christof Warlich

DDD said:
This problem is about Runtime Type Identification.
The following codes are refered from ANSI/ISO C++ Professional
Programmer's Handbook - Chapter 7

Operator typeid takes either an object or a type name as its argument
and returns a matching const type_info object.
The dynamic type of an object can be examined as follows:
OnRightClick (File & file)
{
if ( typeid( file) == typeid( TextFile ) )
{
//received a TextFile object; printing should be enabled
}
else
{
//not a TextFile object, printing disabled
}
}
This check will only be true if file has exactly the type of TextFile.
If file is an object that is instantiated from a class that is derived
from TextFile, the check will be false.

Anyway, thanks for your help.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top