2

機能を一連のプラグイン ポリシーに依存させたいクラスがあります。しかし、クラスを任意の数のクラスから派生させる方法がわかりません。

以下のコードは、私が達成しようとしているものの例です。

// insert clever boost or template trickery here
template< class ListOfPolicies >
class CMyClass : public ListOfPolicies 
{
public:
    CMyClass()
    {
        // identifiers should be the result of OR-ing all 
        // of the MY_IDENTIFIERS in the TypeList.
        DWORD identifiers; 

        DoSomeInitialization( ..., identifiers, ... );
    }

    int MyFunction()
    {
        return 100;
    }

    // ...
};

template< class T >
class PolicyA
{
public:
    enum { MY_IDENTIFIER = 0x00000001 };

    int DoSomethingA()
    {
        T* pT = static_cast< T* >( this );
        return pT->MyFunction() + 1;
    };

    // ...
};

template< class T >
class PolicyB
{
public:
    enum { MY_IDENTIFIER = 0x00000010 };

    int DoSomethingB()
    {
        T* pT = static_cast< T* >( this );
        return pT->MyFunction() + 2;
    };

    // ...
};

int _tmain(int argc, _TCHAR* argv[])
{
    CMyClass< PolicyA > A;
    assert( A.DoSomethingA() == 101 );

    CMyClass< PolicyA, PolicyB > AB
    assert( AB.DoSomethingA() == 101 );
    assert( AB.DoSomethingB() == 102 );

    return 0;
}

ありがとう、ポールH

4

3 に答える 3

6

Boost.MPLライブラリの場合:

//Warning: Untested
namespace bmpl = boost::mpl;
template<class Typelist>
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type
{
...
};

使用されます:

X<bmpl::vector<Foo, Bar, Baz> > FooBarBaz;

「すべての MY_IDENTIFIER を OR する」部分については、次の行に沿った何か:

//Warning: still not tested:
enum {OR_ED_IDENTIFIERS = 
    bmpl::fold<Typelist, bmpl::int_<0>, bmpl::bitor_<_1, _2> >::value;
}
于 2009-10-20T21:46:32.300 に答える
4

型の任意のリストから導出するには、任意の数の型をリストする必要があります。そのために、私は型リストしか知りません。これを次のコードに使用します。

class nil {};

template< typename H, class T >
struct type_list {
    typedef H head_type;
    typedef T tail_type;
};

そのため、型リスト内のすべての型から派生するテンプレートを作成できます。

template< class TL >
struct derivator;

template<>
struct derivator<nil> {};

template< typename H, typename T >
struct derivator< type_list<H,T> > : public H
                                   , public derivator<T> {};

これを次のコードでテストしました

class A {};   void a(A) {std::cout << "A\n";}
class B {};   void b(B) {std::cout << "B\n";}
class C {};   void c(C) {std::cout << "C\n";}

class X : public derivator< type_list<A 
                          , type_list<B 
                          , type_list<C 
                          , nil > > > > {};

int main(void)
{
    X x;
    a(x);
    b(x);
    c(x);

    return 0;
}

VCとComeauの両方がこのコードを気に入っているようで、印刷されます

A
B
C

だからうまくいくようです。

于 2009-10-20T21:46:18.350 に答える
0

型リストを使用した可能な実装:

#include <cstdlib>

/**
 * Base classes that you want to inherit from.
 */
struct A
{
    A() {std::cout << "A()" << std::endl;}
};

struct B
{
    B() {std::cout << "B()" << std::endl;}
};

struct C
{
    C() {std::cout << "C()" << std::endl;}
};

/**
 * Typelists
 */
struct NullType {};

template <typename H, typename T>
struct InheritanceList : public H, public T
{
    typedef H head_t;
    typedef T tail_t;
};

template <typename H>
struct InheritanceList<H,NullType> : public H
{
    typedef H        head_t;
    typedef NullType tail_t;
};

#define INHERITANCE_LIST_1(x)     InheritanceList<x,NullType>
#define INHERITANCE_LIST_2(x,y)   InheritanceList<x,InheritanceList<y,NullType>
#define INHERITANCE_LIST_3(x,y,z) InheritanceList<x,InheritanceList<y,InheritanceList<z,NullType> > >

/**
 * Your class
 */
struct MyClass : public INHERITANCE_LIST_3(A,B,C)
{
};

/**
 * Entry point
 */
int main( int argc, char** argv )
{
    MyClass mc;

    return EXIT_SUCCESS;
}
于 2009-10-21T08:40:58.447 に答える