Hi Jeff,
The worst of all possible worlds is to test the argument's run-time type
with a switch statement, if-else block, or the like (the "switch on
type" approach).
The next worst of all possible worlds is to code a different version of
the function for each derived type that may be an argument to it (the C
approach).
Hmm, this leads me to the next question:
given the case you have to call a function depending on two Instances of a
class, what shall we do then?
I append a small example to demonstrate you the Problem I have. Additionally
there is another constraint: no function overloading (a real-world reason
:-( ) for the final function "kicking" which is called out of main.
Please take a closer look at the function kicking. The if..else table is a
real horror. But how to solve it in an easier way?
Regards,
Patrick
// CODE STARTS
#include <iostream>
// small hierachy
// abstact base class, virtual for RTTI
class mama {
protected:
mama() {};
virtual ~mama() {};
};
class daughter : public mama {};
class son : public mama {};
class son2 : public mama {};
// small action functors
template <typename T1,typename T2> struct kick;
template <typename T> struct kick<T,T>
{
void operator()() { std::cout << "Look mum, I am kicking me." <<
std::endl; }
};
template <> struct kick<son,daught er>
{
void operator()() { std::cout << "He, do not kick girls !!!" <<
std::endl; }
};
template <> struct kick<son2,daugh ter>
{
void operator()() { std::cout << "He, do not kick girls !!!" <<
std::endl; }
};
template <> struct kick<daughter,s on>
{
void operator()() { std::cout << "Aua, that hurts." << std::endl; }
};
template <> struct kick<daughter,s on2>
{
void operator()() { std::cout << "Aua, that hurts." << std::endl; }
};
template <> struct kick<son,son2>
{
void operator()() { std::cout << "son2 is crying running to mama" <<
std::endl; }
};
template <> struct kick<son2,son>
{
void operator()() { std::cout << "son is kicking back" << std::endl; }
};
// function which shall be executed
// uuuuuhhhhh, this is really ugly,
// just for a call kick<instancety pe(fam1_),insta ncetype(fam2_)> ()();
// I really expect typos
void kicking(const mama & fam1_,const mama & fam2_)
{
std::cout << typeid(fam1_).n ame() << " tries to kick ";
std::cout << typeid(fam2_).n ame() << ": ";
if ( typeid(daughter ) == typeid(fam1_) )
if ( typeid(daughter ) == typeid(fam2_) )
kick<daughter,d aughter>()();
else if ( typeid(son) == typeid(fam2_) )
kick<daughter,s on>()();
else if ( typeid(son2) == typeid(fam2_) )
kick<daughter,s on2>()();
else throw "Ups, what happend ?";
else if ( typeid(son) == typeid(fam1_) )
if ( typeid(daughter ) == typeid(fam2_) )
kick<son,daught er>()();
else if ( typeid(son) == typeid(fam2_) )
kick<son,son>() ();
else if ( typeid(son2) == typeid(fam2_) )
kick<son,son2>( )();
else throw "Ups, what happend ?";
else if ( typeid(son2) == typeid(fam1_) )
if ( typeid(daughter ) == typeid(fam2_) )
kick<son2,daugh ter>()();
else if ( typeid(son) == typeid(fam2_) )
kick<son2,son>( )();
else if ( typeid(son2) == typeid(fam2_) )
kick<son2,son2> ()();
else throw "Ups, what happend ?";
else throw "Ups, what happend ?";
}
// examples
int main()
{
kicking( son() , daughter() );
kicking( daughter() , son() );
kicking( son() , son() );
kicking( son() , son2() );
kicking( son2() , son() );
kicking( son2() , daughter() );
return 0;
}
// CODE ENDS