I have a template function which takes in objects. I need to determine whether the object is derived from a particular base class. If it is derived from the base class, I ne
A true template specialization would be even better :)
class A {
public:
char c;
};
template <typename T> void foo(const T & t)
{
std::cout << "this is generic.";
}
template <> void foo(const A & a)
{
std::cout << "this is specialized.";
}
int main(int argc, char * argv[])
{
foo(A());
foo(int());
}
Boost.TypeTraits boost::is_base_of
const bool is = boost::is_base_of<Base,Derived>::value;
How does `is_base_of` work?
Without knowing the exact nature of the additional work you want to do, there could be 2 ways might approach this.
Option 1: Say the function you want to call is foo(). You could implement foo() on both baseA and testB. baseA::foo() can give you your extra work while testB:foo() would just do nothing. But this style wouldn't make sense if foo() doesn't belong in either of those 2 classes.
Optional 2: Specialize functionA for baseA (or optionally testB as well)
void function_specialized(baseA* param)
{
// Do your extra work
// Then call the common functionA
functionA<baseA>(*param);
}
template<typename T>
functionA(const T& value)
{
//...
}
You can do template specialization which will be fully static:
template <typename T>
void function(const T& value)
{
common_task();
}
template <>
void function<A>(const A& value)
{
common_task();
// special A tasks
}
You can use Run Time Type Identification (RTTI) for this purpose. An Example follows:
class A{
public:
virtual void func(){cout << "Base" << endl;}
virtual ~A(){}
};
class B:public A{
public:
void func(){cout << "Derived" << endl;}
};
int main(){
A * d1 = new B();
B * d2;
d1 -> func() ;
d2 = dynamic_cast<B*>(d1);
if(d2 != NULL)
cout << "Base exists" << endl;
else
cout << "No relation" << endl;
return 0;
}
It is somewhat difficult to mix templates and inheritance.
The trouble:
template <typename T>
void function(T const& t);
void function(A const& a);
If you use struct B: A {}:
, then the template version is preferred, because no conversion is required, and it is therefore a "better" match.
If you have access to the definition of the template version, you can use a combination of is_base_of
and disable_if
.
template <typename T>
typename boost::disable_if< boost::is_base_of<A, T> >::type function(T const& t);
This simple modification makes use of SFINAE, basically it generates an error when trying to instantiate function
for any class derived from A
and the C++ standard specifies that if a function may not be instantiated then it is to be removed from the set of overloads considered without triggering a compiler error.
If you do not have access to the template definition of function
, you're out of luck.