4

以下のコードがコンパイルされない理由を理解するのに苦労しています-誰か説明してもらえますか?

基本クラスから派生クラスのtypedefにアクセスするにはどうすればよいですか?

template<class Derived>
struct Test
{
    template<class T>
    typename Derived::value_type foo(T);
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};
4

2 に答える 2

6

宣言の時点ではDerivedDerivedはまだ完全な型ではありません。宣言を始めたばかりです。したがって、特殊化では、テンプレート引数は不完全な型であるため、循環論理である--Test<Derived>などのネストされた名前を参照してはなりません。Derived::value_type

戻り型を別の引数にすることで、問題を回避できます。

template <typename T, typename R> struct Test
{
    template <typename U> R foo(U);
};

template <typename R>
struct BasicDerived : public Test<BasicDerived, R>
{
    typedef R value_type;
};

typedef BasicDerived<int> Derived;
于 2012-08-09T12:28:15.760 に答える
5

基本クラスのテンプレートクラスまたはテンプレートクラスのメンバーに直接アクセスすることはできませんtypedef。その時点では、完全な型ではないためです。これを許可すると、循環動作につながります。

template<class Derived>
struct Test
{
    typedef typename Derived::value_type foo;
};

struct Derived : public Test<Derived>
{
    typedef Test<Derived>::foo value_type;
};

ただし、メソッド内でテンプレートクラスのメンバーを参照することはできます。これらのメンバーは、後でインスタンス化されるまではインスタンス化されないためです。

template<class Derived>
struct Test
{
    void foo() { typename Derived::value_type bar; }
};

struct Derived : public Test<Derived>
{
    typedef int value_type;
};

または、目的に応じて、typedefを追加のテンプレートパラメーターとして渡すことができます。

template<typename value_type, class Derived>
struct Test
{
    template<class T>
    value_type foo(T);
};

struct Derived : public Test<int, Derived>
{
    typedef int value_type;
};
于 2012-08-09T12:32:34.293 に答える