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 にアクセスするために型名が必要ない理由がわかりません。
名前検索ルールで何が欠けていますか?