70

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
};

BI で Vec_t が認識されず、明示的に記述する必要があるというエラーが表示されるのはなぜですか?

typename A<T>::Vec_t v;
4

7 に答える 7

46

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

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

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

于 2009-10-29T11:54:30.877 に答える
43

テンプレートの場合、従属名と従属名と呼ばれるものがあります。

name がテンプレート パラメーター T に依存する場合は、その依存名であり、パラメーター T に依存しない名前は独立した名前です。

ルールは次のとおりです。コンパイラは、依存しない名前 (Vec_t など) を検索するときに、依存する基底クラス (A など) を検索しません。その結果、コンパイラはそれらが型であることは言うまでもなく、それらが存在することすら知りません。

コンパイラはそれがVec_tわかるまでそれが型であると仮定することはできません.TA<T>A<T>:: Vec_t

したがって、解決策は typename を使用することです

 typename A<T>::Vec_t v;  ← good

このhttps://isocpp.org/wiki/faq/templates#nondependent-name-lookup-typesに目を通すことをお勧めします。

古い (壊れた) リンク: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18

于 2009-10-29T11:49:09.397 に答える
8

Vec_tコンパイラは、型に名前を付けることが確実ではないためです。たとえば、特定の を持たないA<T>ように特化されT=intている場合があります。typedef

于 2009-10-29T11:38:38.353 に答える
2

コンパイラはどこから来たVec_tのか分からないため、の使用を明示的に修飾する必要があります。Vec_t

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

于 2009-10-29T11:40:21.797 に答える
1

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

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

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

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

于 2009-10-29T11:44:13.157 に答える