0

わかりました、昨日、ほぼ同じ質問をここに投稿 しましたが、必要に応じて回答(機能)を変更できませんでした...他のトピックを台無しにしたくなかったので、新しいトピックを開始しました。

したがって、オブジェクトを構成できる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();
}

(int は単なる例です)

だから私はいくつかのテンプレートマジックを持っています:

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」よりも

行動が「Evade from」で構成されている場合は、「performBehaviorEvade」よりも

...

これは非常に短い説明ですが、私の主張がうまくいったことを願っています

4

1 に答える 1

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)); 
}
于 2011-08-10T15:33:35.540 に答える