7

テンプレートクラスを使用してCRTPを実装しようとすると、次のサンプルコードでエラーが発生します。

#include <iostream>

template<class T> class Traits
{
    public:
        typedef typename T::type type; // <- Error
                                       // : "no type named 'type' in 'class MyClass<double, 3u, 3u>'
        static const unsigned int m_const = T::m_const;
        static const unsigned int n_const = T::n_const;
        static const unsigned int size_const = T::m_const*T::n_const;
};

template<class T0> class Crtp
{
    public:
        typedef typename Traits<T0>::type crtp_type;
        static const unsigned int size = Traits<T0>::size_const; // <- This is OK
};

template<typename TYPE, unsigned int M, unsigned int N>
class MyClass : public Crtp< MyClass<TYPE, M, N> >
{
    public:
        typedef TYPE type;
        static const unsigned int m_const = M;
        static const unsigned int n_const = N;
};

int main()
{
    MyClass<double, 3, 3> x;
    std::cout<<x.size<<std::endl;
    return 0;
}

この問題の原因や修正方法がわかりません。

実際、私の目標は、CRTPクラスが派生クラスのテンプレート引数をCRTPクラスのテンプレート引数として渡すことなく知る必要があることです。

これを実装する方法について何かアイデアはありますか?

編集(最初のものに関連して):私のCRTPクラスは、異なる数のテンプレートパラメーターを持つ派生クラスを処理できる必要があります

4

1 に答える 1

7

問題は、MyClassインスタンス化する独自の基本クラスリストが不完全であるということですCrtp<MyClass>。ただし、インスタンス化にCrtp<MyClass<...>>はインスタンス化が必要Traits<MyClass<...>>であり、インスタンス化MyClass<...>::typeには不完全であるため不可能です。循環依存があります。

実際、私の目標は、CRTPクラスが派生クラスのテンプレート引数を認識している必要があることです。

これは、次のように、部分的な特殊化とtemplate-template-parameterを使用して実行できます。

#include <iostream>

template<typename T> class Crtp;

template<template<typename, unsigned, unsigned> class T, typename U, unsigned M, unsigned N>
class Crtp< T<U, M, N> >
{
    public:
        typedef U crtp_type;
        static const unsigned int size = M * N;
};

template<typename TYPE, unsigned int M, unsigned int N>
class MyClass : public Crtp< MyClass<TYPE, M, N> >
{
};

int main()
{
    MyClass<double, 3, 3> x;
    std::cout<<x.size<<std::endl;
    return 0;
}
于 2012-08-03T12:57:08.560 に答える