хорошо, вчера я разместил почти идентичный вопрос здесь , но я не смог изменить ответ (рабочий) в соответствии с моими потребностями ... Я не хотел связываться с другой темой, поэтому яначали новый.
Итак, у меня есть 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 , чтобы сделать его лучше для чтения.
Спасибо!
РЕДАКТИРОВАТЬ: (задавать вопросы в комментариях)
Я строю систему для ИИ и хочу решить как можно больше вещейво время компиляции, насколько я могу. В этом случае я строю систему для поведения движения. Мой код обеспечивает много типов поведения, таких как «Перейти к точке», «Уклониться от», «Избегать препятствий»les "и т. д. Это поведение в приведенном выше примере упоминается как A a, B. У каждого из этих поведений есть метод, подобный" executeBehavior ", и его тип возвращаемого значения можно комбинировать с другим" executeBehavior ".
Так что я хочусобрать определенное поведение во время компиляции.например.просто A или A + C + D + F и т.д. ...
, а затем в моем обновлении сделайте что-то вроде:
, если поведение состоит из «Перейти к точке», чем «executeBehaviorGoTo»
если поведение состоит из "уклонения от", чем "executeBehaviorEvade"
...
это очень очень краткое объяснение, но надеюсь, что я высказал свою точку зрения