«Унаследованные» типы с использованием CRTP и typedef - PullRequest
5 голосов
/ 01 мая 2010

Следующий код не компилируется. Я получаю сообщение об ошибке: ошибка C2039: «Asub»: не является членом «C»

Может ли кто-нибудь помочь мне понять это?

Пробовал VS2008 & 2010 компилятор.

template <class T>
class B
{
    typedef int Asub;

public:
 void DoSomething(typename T::Asub it)
 {

 }
};

class C : public B<C>
{
public:
 typedef int Asub;

};

class A
{
public:
 typedef int Asub;

};


int _tmain(int argc, _TCHAR* argv[])
{
 C theThing;
 theThing.DoSomething(C::Asub());

 return 0;
}

1 Ответ

8 голосов
/ 01 мая 2010

Вы немного несправедливы по отношению к компилятору здесь - C неполон без B<C> полностью известного и при обработке B<C>, C все еще не завершенный тип. Есть похожие темы на comp.lang.c ++. Moderated и comp.lang.c ++ .

Обратите внимание, что это работает, если вы задержите использование, переместив его в определение функции-члена, например ::

struct C : B<C> {
    void f() { typedef typename C::Asub Asub; }
};

Вы можете обойти эту проблему, передавая типы явно вверх:

template<class T, class Asub> struct B { /* ... */ };
class C : B<C, int> { /* ... */ };

... или переместив их в какой-нибудь класс черт, если вам нужно пройти больше:

template<class T, class Traits> struct B {
  void DoSomething(typename Traits::Asub it) {}
};

struct CTraits {
    typedef int Asub;
};

struct C : B<C, CTraits> {
    typedef CTraits::Asub Asub;    
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...