質問

typedefのみを含む基本クラスを定義しようとしています。

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
private:
    Vec_t v;  // fails - Vec_t is not recognized
};

BでVec_tが認識されないというエラーを受け取り、明示的に記述する必要があるのはなぜですか?

typename A<T>::Vec_t v;
役に立ちましたか?

解決

この質問は重複していると思いますが、今は見つけることができません。 C ++ Standardは、14.6.2 / 3に従って名前を完全に修飾する必要があると述べています。

  

クラステンプレートまたはクラステンプレートのメンバーの定義で、クラステンプレートの基本クラスがテンプレートパラメータに依存している場合、非修飾名のルックアップ中に基本クラススコープは検査されません >クラステンプレートまたはメンバーの定義の時点で、またはクラステンプレートまたはメンバーのインスタンス化中に。

UPD:最終的に重複が見つかりました:

他のヒント

Vec_t が型に名前を付けるかどうかはコンパイラーに確信がないためです。たとえば、 A&lt; T&gt; は、 T = int に特化して、特定の typedef を持たない 場合があります。

完全を期すため、この迷惑を少し軽減する方法を以下に示します。

  • 派生クラスでこれらの型を再定義するか、より良い-と同様に メソッド-
  • 派生クラスのスコープにある using宣言でこれらの名前をインポートするだけです:

template<typename T>
class A
{
public:
    typedef std::vector<T> Vec_t;
};


template<typename T>
class B : public A<T>
{
public:
    using typename A<T>::Vec_t;
    // .........

private:
    Vec_t v;
};

派生クラスで継承された typedef について複数の言及がある場合に役立ちます。また、毎回 typename を追加する必要はありません。

Vec_t の由来をコンパイラが認識しないため、 Vec_t の使用を明示的に修飾する必要があります。

クラステンプレートAは特殊化されている可能性があるため、Aの構造については何も想定できません。特殊化には、typedefではない Vec_t が含まれるか、メンバー Vec_t がまったく含まれない場合があります。

Vec_tは依存名ではないため、コンパイラはテンプレート(この場合はベースクラス)をインスタンス化せずに、それが何であるかを知る必要があります。本当に違いはありません:

template <class T>
class X
{
    std::string s;
}

名前もテンプレート引数Tに依存しないため(コンパイラが想定できる限り)、ここでもコンパイラはXがインスタンス化されていない場合でもstd :: stringについて知る必要があります。

全体として、テンプレートの基本クラスのtypedefは、派生クラスで使用するのではなく役に立たないようです。ただし、typedefはユーザーにとっては便利です。

この概念は、 std :: vector&lt; T&gt; の使用方法に関連付けることができます。たとえば、 std :: vector&lt; int&gt;がある場合Foo 。ここで、 iterator のように、そのメンバー型のいずれかを使用することにしました。このシナリオでは、明示的に言及しています

std::vector<int>::iterator foo_iterator;

同様に、 template&lt; typename T&gt;の Vec_t のパブリックメンバータイプを使用するには、クラスA 、明示的に宣言する必要があります

A<T>::Vec_t v;
OR
A<int>::Vec_t int_type;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top