4

私は「テンプレートテンプレートテンプレート」を実装しようとしました-私のニーズを満たすためのテンプレートクラスです(私はテンプレートメタプログラミングを使用するのはまったく新しいです)。残念ながら、次のトピックは遅すぎます。 テンプレートテンプレートパラメータ

それでも、以下のようなものを実装する必要があります。

コンパイラによると、最後のtypedefは機能していません。よくわかりませんが、これは3倍のテンプレート制限の制限によるものだと思います。この単純な例で3xtemplate定義をバイパスする可能性はありますか?

template < typename TValueType >
class ITTranslator
{
public:
    ITTranslator() = 0;
    virtual ~ITTranslator() = 0;
    virtual void doSomething() = 0;
}

template < typename TValueType >
class TConcreteTranslator1 : public ITTranslator<TValueType>
{
public:
    TConcreteTranslator1(){}
    ~TConcreteTranslator1(){}
    void doSomething() {}
}

template < typename TValueType >
class TConcreteTranslator2 : public ITTranslator<TValueType>
{
public:
    TConcreteTranslator2(){}
    ~TConcreteTranslator2(){}
    void doSomething() {}
}

template < 
    typename TValueType, 
    template < typename TValueType > class TTranslatorValueType 
    >
class ITClassifier
{
public:
    ITClassifier() = 0;
    virtual ~ITClassifier() = 0;
}

template < 
    typename TValueType, 
    template < typename TValueType > class TTranslatorValueType 
    >
class TConcreteClassifier1 : public ITClassifier<TValueType,TTranslatorValueType >
{
public:
    TConcreteClassifier1() {}
    ~TConcreteClassifier1() {}
    void dodo(){}
}


template < 
    typename TValueType,
    template <typename TValueType> class TTranslatorValueType,
    template <template<typename TValueType> class TTranslatorValueType> class TClassifierValueType
 >
class ITAlgorithm
{
public:
    ITAlgorithm()=0;
    virtual ~TAlgorithm()=0;
    virtual run() = 0;
}


template < 
    typename TValueType,
    template <typename TValueType> class TTranslatorValueType,
    template <template<typename TValueType> class TTranslatorValueType> class TClassifierValueType
 >
class TConcreteAlgorithm1 : public ITAlgorithm<TValueType,TTranslatorValueType,TTranslatorValueType>
{
public:
    TConcreteAlgorithm1 (){}
    ~TConcreteAlgorithm1 (){}
    run()
    {
        TClassifierValueType< TTranslatorValueType>* l_classifier_pt = new TClassifierValueType< TTranslatorValueType>( );
        // add this object to a internal list...
    }
}



int main()
{
    typedef TConcreteTranslator1< cvbase::uint32_t > translator_t;
    typedef TConcreteClassifier1< cvbase::uint32_t, TConcreteTranslator1> classifier_t;
    typedef TConcreteAlgorithm1 < cvbase::uint32_t, TConcreteTranslator1, TConcreteClassifier1> algorithm_t; // not possible
    return 0;
}

どうもありがとうございました、私は本当にどんな助けにも感謝します!

編集:私は私のリストを拡張しました(私はそれがコンパイルされないことをかなり確信しています:))私が私の奇妙な概念を使用している理由を示すために:)

4

3 に答える 3

2

この辺りでテンプレートテンプレートパラメータを渡す必要は実際にはありません。通常、通常のテンプレート引数を取り、適切なデフォルトを指定できます。

template<typename ValueType>
struct translator {};

template<typename ValueType, typename Translator = translator<ValueType>>
struct Classifier {};

template<typename ValueType, 
         typename Translator = translator<ValueType>, 
         typename Classifier = classifier<ValueType, Translator>
         >
struct Algorithm {};

これは、アロケータ対応コンテナの場合と同じ方法で行われます。

そして、恐ろしいハンガリアン記法の接頭辞を廃止してください。

注意:コンストラクタとデストラクタの使用法から、基本的なC++を実際に理解していないようです。より簡単な概念を理解する前に、テンプレートを避けたいと思うかもしれません。

于 2012-10-17T21:04:36.887 に答える
1

はい、(任意のレベルの)テンプレートテンプレートパラメータを回避することは可能です。

テンプレートは基本的にタイプレベルの関数です。タイプをフィードして、別のタイプを返します。

テンプレートテンプレートパラメータはそれ自体がタイプレベルの関数であり、そのようなパラメータを受け入れるテンプレートは高階タイプレベルの関数です。

テンプレートテンプレートパラメータを使用せずに、メンバーテンプレートを使用して高次の型レベル関数を実装することができます。デザインに必要かどうかはわかりませんが、簡単で汚い例を次に示します。

// regular type, a.k.a. zeroth-order type-level function, 
// a.k.a. "type of kind *"
struct N
{
    int a;
};

// a first-order type-level function, a.k.a. "type of kind *->*"
// it is wrapped in a regular type
struct B
{
    template <class A> struct Impl
    {
        void foo(A a)
        {
            int aa = a.a;
        }
    };
};

// a second-order type-level function 
// that accepts a (wrapped) first-order type function
// and also a regular type. the kind of it would be (*->*)->*->*
// it applies its first argument to its second argument
struct Z
{
    template <class X, class Y> struct Impl
    {
        typename X::template Impl<Y> ya;
        void bar()
        {
            ya.foo(Y());
        }
    };
};

// now this is something: a third-order type-level function
// that accepts a (wrapped) second-order type-level function
// and a (wrapped) first-order type-level function
// and a zeroth-order type-level function
// it applies its first argument to its second and third arguments
// it is also wrapped in a regular type for consistency
// try to figure out its kind
struct T
{
    template <class P, class Q, class R> struct Impl 
    {
        typename P::template Impl<Q, R> yb;
        void baz()
        {
          yb.bar();
        }
    };
};

T::Impl<Z, B, N> tt;
于 2012-10-17T22:31:28.617 に答える
0

この場合、実際にはテンプレートパラメータは必要ありません。基本的に、唯一の変数タイプはTValueTypeですよね?他のタイプは、TValueTypeを使用してクラス本体で解決できます。

このようなもの:

template < 
    typename TValueType
 >
class TAlgorithm
{
public:
    // TTranslator <TValueType> whatever
    // TTranslatorValueType <TValueType> whatever
    TAlgorithm(){}
    ~TAlgorithm(){}
}
于 2012-10-17T21:01:33.183 に答える