Как делают нас определение типа или переопределяют шаблонный вложенный класс в подклассе?

Рассмотрите следующее:

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //How do we typedef of redefine Base<T>::Nested?
    using Base<T>::Nested; //This does not work
    using Base<T>::template<typename U> Nested; //Cannot do this either
    typedef typename Base<T>::template<typename U> Nested Nested; //Nope..

    //now we want to use the Nested class here
    template <typename U>
    Class NestedDerived : public Nested { };

    //or like this:
    Nested<int> nestedVar; // obviously does not work
};

Как использовать шаблонный Вложенный класс в Производном классе? Действительно ли это возможно сделать в текущей версии стандарта C++?

7
задан Georg Fritzsche 18 February 2010 в 03:07
поделиться

4 ответа

На самом деле использование работает так, как рекламируется, просто оно не избавляет от проблемы зависимого имени в шаблоне и в настоящее время не может напрямую псевдонизировать шаблоны (будет исправлено в C++0x):

template <class T>
struct Base {
    template <class U> struct Nested {};
};

template <class T>
struct Derived : Base<T> {
    using Base<T>::Nested;

    // need to prefix Nested with template because
    // it is a dependent template:
    struct X : Base<T>::template Nested<int> {};

    // same here:
    template<class U>
    struct Y : Base<T>::template Nested<U> {};

    // data member, typename is needed here:
    typename Base<T>::template Nested<int> data;
};

void f() { 
    Derived<int>::Nested<int> n; // works fine outside
}

Есть еще одна возможная загвоздка при использовании Derived::Nested в шаблонах, но это опять же проблема зависимого имени, а не наследования:

template<class T>
void g() {
    // Nested is a dependent type and a dependent template, thus
    // we need 'typename' and 'template':
    typedef typename Derived<T>::template Nested<int> NestedInt;
}

Просто помните, что имена, зависящие от аргументов шаблона, должны иметь

  • префикс typename, если это зависимый тип: typename A::B
  • непосредственно префикс с template, если это зависимый шаблон: A::template f()
  • оба, если оба: typename A::template B
  • typename является незаконным в списках базовых классов: template struct A : B, C::template D {};
10
ответ дан 6 December 2019 в 21:13
поделиться

Я все еще не уверен на 100%, что вы хотите, но вы можете попробовать.
Это скомпилировано в Visual Studio

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //now we want to use the Nested class here
    template <typename U>
    class NestedDerived : public Nested<U> { };
};

int _tmain(int argc, _TCHAR* argv[])
{
Base<int>::Nested<double> blah2;
Derived<int>::NestedDerived<int> blah;

return 0;
}
0
ответ дан 6 December 2019 в 21:13
поделиться

Кажется, это работает:
(EDIT: добавил еще несколько строк, чтобы показать первый шаблонный оператор. И спасибо Самиру Талвару за исправление моего форматирования! )

template <typename T, typename U> 
class Derived : public Base<T> { 
  public: 
    typedef typename Base<T>::template Nested<U> Nested;

    class NestedDerived : public Nested { }; 

    Nested nestedVar;
};
2
ответ дан 6 December 2019 в 21:13
поделиться

Попробуйте следующее:

template <typename T>
class Base {
  public:
    template <typename U>
    class Nested { };
};

template <typename T>
class Derived : public Base<T> {
  public:
    //How do we typedef of redefine Base<T>::Nested?
    //using Base<T>::Nested; //This does not work
  //using Base<T>::template<typename U> Nested; //Cannot do this either
  //typedef typename Base<T>::template<typename U> Nested Nested; //Nope..

    //now we want to use the Nested class here
  template <typename U>
  class NestedDerived : public Base<T>::template Nested<U> { };
};

int main()
{
  Base<int>::Nested<double> nested;

  Derived<int>::NestedDerived<double> nested_derived;

  return 0;
}

Скомпилировано нормально с использованием gcc 4.3.3 на Slackware 13

0
ответ дан 6 December 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: