2

CRTP のようなパターンを実装するテンプレート クラスの階層があります。エラーでマークされた行で名前の検索が失敗し、「ここにエラーはありません」とマークされた行で名前の検索が成功する理由がわかりません。

class CPublishedTypes
{
    public:
    typedef int published_t;
};

template<class Derived, class PublishedTypes> class Cbase: public PublishedTypes
{
    public:
        Cbase():ibase_(42){}
    private:
        published_t ibase_; //error: 'published_t' does not name a type       
};

template<class Derived> class Cmiddle : public Cbase<Derived, CPublishedTypes>
{    
    public:
        Cmiddle():imiddle_(42){}
    private:
        published_t imiddle_; //error: 'published_t' does not name a type    
};

class Cderived : public Cmiddle<Cderived>
{
    public:
        Cderived():iderived_(42){}
    private:
        published_t iderived_; // No errors here
};

int main(int argc, char *argv[])
{
    Cderived derived;
    return 0;
}

「typename」を使用しても役に立ちません。

C++ FAQ では、類似しているが同一ではない問題について説明しています: http://www.parashift.com/c++-faq/nondependent-name-lookup-types.html

Cbase は、テンプレートパラメータである PublishedTypes からパブリックに継承しますが、テンプレートクラスではありません。CPublishedTypes::published_t にアクセスできない理由がわかりません。

Cderived は Cmiddle を継承し、Cmiddle は Cbase を継承します。したがって、ここで CPublishedTypes::published_t にアクセスするために型名が必要ない理由がわかりません。

名前検索ルールで何が欠けていますか?

4

2 に答える 2

3

テンプレート パラメーターに依存する型にはプレフィックスを付ける必要がありtypename、テンプレート基本クラスの場合は親クラスの名前を付ける必要があります。ただし、最後の例では、クラスはテンプレートでCderivedはないため、テンプレートのインスタンス化までタイプのルックアップが遅延されないため、これは必要ないため、通常のルックアップ ルールが適用されます。

于 2013-10-04T10:06:51.603 に答える