How to find, from which Types is object composed of?
ok, yesterday I posted almost identical question here , but I wasn't able to modify the answer(working) to my needs... I did not want to mess the other topic, so I have started new one.
So, I have 2 (actually about 15) structs, which can composed an object
class MyBase{};
template <typename Super, typename T1, typename T2>
struct A : public Super
{
void doStuffA() { cout<<"doing something in A"; }
};
template <typename Super, typename T1, typename T2>
struct B : public Super
{
void doStuffB() { cout<<"doing something in B"; }
};
then I have:
template <typename ComposedType, typename T1, typename T2>
class Combined
{
ComposedType m_cT;
public:
Combined(const ComposedType & c) : m_cT(c) { }
typedef A<null, T1, T2> anull;
typedef B<null, T1, T2> bnull;
void update()
{
typedef typename split<ComposedType>::Ct Ct;
typedef typename split<ComposedType>::At At;
//this I want
if( composed of A )
m_cT.doStuffA();
if( composed of B )
m_cT.doStuffB();
}
};
and I want to use it like:
int main()
{
typedef A<B<MyBase,int,int>,int,int> ComposedType1;
typedef B<MyBase,int,int> ComposedType2;
ComposedType1 ct1;
ComposedType2 ct2;
Combined<ComposedType1, int, int> cb1(ct1);
cb1.update();
Combined<ComposedType2, int, int> cb2(ct2);
cb2.update();
}
(ints are just for example purposes)
So I have some template magic:
struct null{};
template<typename>
struct split
{
typedef null Ct;
typedef null At;
};
template<template<typename> class C, typename T>
struct split<C<T> >
{
typedef C<null> Ct; //class template
typedef T At; //argument type
};
template<template<typename> class C>
struct split<C<MyBase> >
{
typedef C<null> Ct; //class template
typedef MyBase At; //argument type
};
but I can not make it works :(
I know there is a lot of code, but this is actually minimal example... I have posted this code to ideone, to make it better for reading.
Thank you!
EDIT: (to ask questions in comments)
I am building system for AI and want to solve as much thing in compile time as I can. In this case, I am building system for movement behavior. My code supply many types of behavior like "Go to point", "Evade from", 开发者_运维问答 "Avoid obstacles" etc. This behaviors are in example above mentioned as A a, B. Each of this behavior has method like "performBehavior" and its return type can be combined with other "performBehavior".
So I want to put together specific behavior at compile time. eg. just A or A+C+D+F etc...
and then in my update do something like:
if behavior is consisted of "Go to point", than "performBehaviorGoTo"
if behavior is consisted of "Evade from", than "performBehaviorEvade"
...
this is very very short explanation, but hope I have made my point
You can do that with function overloading:
template <typename Super, typename T1, typename T2>
void doStuff(A<Super, T1, T2>& a) { a.doStaffA(); }
template <typename Super, typename T1, typename T2>
void doStuff(B<Super, T1, T2>& b) { b.doStaffB(); }
And then:
// ...
void update()
{
//this I want
//if( composed of A )
// m_cT.doStuffA();
//if( composed of B )
// m_cT.doStuffB();
doStuff(m_cT);
}
It is not clear, whether you want to chain calls for A<B<...> >
. If you do, then something like the following would do:
template <class T>
void doStuff(T&) { /* do nothing */ }
template <typename Super, typename T1, typename T2>
void doStuff(A<Super, T1, T2>& a) {
a.doStaffA();
doStuff(static_cast<Super&>(a));
}
template <typename Super, typename T1, typename T2>
void doStuff(B<Super, T1, T2>& b) {
b.doStaffB();
doStuff(static_cast<Super&>(b));
}
精彩评论