1

次のコードは問題なく動作します (これは私の他の問題の単純化されたバージョンであり、型が長く、深く、テンプレートが多くなっています):

template<class C>
struct Base
{};

template<class C>
struct Derived : public Base<C>
{
   Derived() : Base<C>()
   {}
};

しかし、基本クラスの完全な型を「書き込む」ことなく、どうすれば基本クラスのコンストラクターを呼び出すことができるでしょうか? たとえば、次のようなことを試しました。

template<class C>
struct Base
{
   typedef Base base_type;
};

template<class C>
struct Derived : public Base<C>
{
   Derived() : base_type() {}
};

int main()
{
   Derived<void> b;
}

しかし、「base_type」は認識されません。gcc がスローするメッセージは次のとおりです。

test3.cpp: In constructor 'Derived<C>::Derived()':
  test3.cpp:100:17: error: class 'Derived<C>' does not have any field
  named 'base_type'

それを解決するにはBase<C>::base_type、コンストラクターに記述する必要がありますが、これはbase_typeそれ自体の存在が無関係になります。

私の節約術は無理ですか?

そして、なぜbase_typeコンストラクターで見つからないのに、これはうまくいくのでしょうか?

int main()
{
   Derived<void>::base_type b;
}

編集: @Jack Aidleyのコメントにより、単純なエイリアスを持つ基本クラスの型を取得するために私が見つけた最良の形式は次のとおりです。

template<typename C> struct Base {};

template<typename C, typename Base>
struct Derived_impl : public Base
{
    Derived_impl() : Base()
    {}
};

template<typename C>
using Derived = Derived_impl<C, Base<C> >;

int main()
{
   Derived<void> b;
}
4

2 に答える 2

2

規格によると

テンプレート定義で使用される名前の宣言を検索する場合、通常の検索規則 (3.4.1、3.4.2) が非依存の名前に使用されます。テンプレート パラメータに依存する名前の検索は、実際のテンプレート引数が判明するまで延期されます (14.6.2)。

base_typeつまり、Baseクラス内で に依存していることをコンパイラに伝える必要がありCます。たとえば、次のように使用できます。

template<class C>
struct Derived : public Base<C>
{
    using typename Base<C>::base_type;

    Derived() : base_type() {}
};

またはこれ

template<class C>
struct Derived : public Base<C>
{
    Derived() : Derived<C>::base_type() {} 

    // or, as you already told, Base<C>::base_type()
};
于 2013-02-07T11:36:40.863 に答える
2

あなたはいつでもこれを行うことができます:

template<class C>
struct Base
{
};

template<class C>
struct Derived : public Base<C>
{
   typedef Base<C> base_type;  // define here

   Derived() : base_type() {}
};

で基本型を参照する場合は理にかなっていますDerived...

于 2013-02-07T11:48:38.903 に答える