2

すべての派生クラスの一般的なロジック (作成など) を持つ public static メソッドを含む基本クラスが与えられます。子クラス テンプレートのパラメータ化型は、基本クラス テンプレートに渡されます (基本クラスの静的メソッドでカスタム静的メソッドにアクセスするために、子クラスの型と共に)。これらの型の組み合わせから、新しい「型」が型定義されます (これは、一部のコードの重複を避けるために基本クラスで行われます)。次に、派生クラスの public セクションで (同様に) 再型定義します。次のように、これらの型定義をヘルパーを含むクラスに使用します。

#include <iostream>
#include <vector>

#include <cmath>
#include <cstdlib>

template< class DERIVED >
class HELPERS;

template< class V, class DERIVED >
struct BASE
{

    typedef typename V::value_type F;

    static
    F some_common_operation()
    {
        return helpers.approximate_x(DERIVED::value()); // some common logic (HELPERS::approximate_x() here) depending on the value of DERIVED::value()
    }

    static
    DERIVED create_biased(F const & x)
    {
        return DERIVED(F(0.5) * (x + some_common_operation()));
    }

protected :

    BASE(F const & x_)
        : x(x_)
    { ; }

    F x;

private :

    static
    HELPERS< DERIVED > const helpers;

};

template< class V, class DERIVED >
HELPERS< DERIVED > const BASE< V, DERIVED >::helpers;

template< class V >
class DERIVED
    : public BASE< V, DERIVED< V > >
{

    typedef BASE< V, DERIVED< V > > B;
    friend B;

public :

    typedef typename B::F F;

    DERIVED(F const & x_)
        : B(x_)
    { ; }

    F shape(F const & y) const
    {
        return y * x;
    }

private :

    static constexpr
    F value()
    {
        return F(2.0L); // custom data
    }

    using B::x;

};

// template< class > class DERIVED1;...

template< class D >
struct HELPERS // set of helpers, that operates on classes derived from BASE
{

    typedef typename D::F F; // error: no type named <F> in <class DERIVED<std::vector<double> >>

    F approximate_x(F const & x) const
    {
        using std::sqrt;
        return sqrt(x);
    }

};

int main()
{
    DERIVED< std::vector< double > > d(2.0L);
    return EXIT_SUCCESS;
}

ヘルパー クラスで定義を取得しようとしていますが、エラーが発生します ( g++ -std=gnu++11 a.cpp )。

a.cpp: In instantiation of «struct HELPERS<DERIVED<std::vector<double> > >»: a.cpp:44:26: required from «struct BASE<std::vector<double>, DERIVED<std::vector<double> > >» a.cpp:47:7: required from «class DERIVED<std::vector<double> >» a.cpp:97:39: required from here a.cpp:85:27: error: no type named «F» in «class DERIVED<std::vector<double> >»

なにが問題ですか?Typedef とそのすべての「祖先」は、クラスのチェーンでアクセスできます (パブリック セクションに配置されます)。

4

1 に答える 1

1

これは鶏卵の問題です。

これは、定義時BASEDERIVEDが完全に定義されていないために発生しています (コンパイラが最初に基本クラスを解決する必要があるため)。DERIVED したがって、 inの typedef にはアクセスできませんHELPER。以下が同様に機能していないことを確認できることを確認します。

template< class V, class DERIVED >
struct BASE
{
    typedef typename V::value_type F;
    typedef typename DERIVED::F G; // <-- error here
    ...
}

試すことができるのは、 の使用を に移動するHELPERDERIVEDVのパラメータとして使用することですHELPER

于 2012-11-21T12:23:24.477 に答える