所以,我有2个(实际上大约15个)结构,它可以组成一个对象
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"; }
};
然后我有:
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();
}
};
我希望像以下一样使用它:
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();
}
(仅用于举报)
所以我有一些模板魔术:
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
};
但我不能使它有效:(
我知道有很多代码,但这实际上是最小的例子......我已将此代码发布到ideone,以便更好地阅读。
谢谢!
编辑:(在评论中提问)
我正在为AI构建系统,并希望在编译中解决尽可能多的事情 时间尽我所能。在这种情况下,我正在构建运动行为系统。 我的代码提供了许多类型的行为,如“转到点”,“逃避”, “避开障碍”等。这种行为在上面的例子中 作为A a,B提到。每个行为都有像“performBehavior”这样的方法 并且它的返回类型可以与其他“performBehavior”结合使用。
所以我想在编译时把特定的行为放在一起。例如。只是A或A + C + D + F等...
然后在我的更新中执行以下操作:
如果行为由“转到点”组成,而不是“performBehaviorGoTo”
如果行为由“逃避”而不是“performBehaviorEvade”
组成...
这是非常简短的解释,但希望我已经说明了我的观点
答案 0 :(得分:2)
你可以通过函数重载来实现:
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(); }
然后:
// ...
void update()
{
//this I want
//if( composed of A )
// m_cT.doStuffA();
//if( composed of B )
// m_cT.doStuffB();
doStuff(m_cT);
}
目前尚不清楚,您是否要为A<B<...> >
调用链接。如果你这样做,那么类似下面的内容就可以了:
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));
}