7 Stimmen

Wie typisiert oder redefiniert man eine geschachtelte Klasse in der Unterklasse?

Bedenken Sie Folgendes:

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

Wie verwendet man die verschachtelte Vorlageklasse in der abgeleiteten Klasse? Ist dies in der aktuellen Version des C++-Standards möglich?

10voto

Georg Fritzsche Punkte 95256

Eigentlich using funktioniert wie angekündigt, es beseitigt nur nicht das Problem mit den abhängigen Namen in der Vorlage und kann derzeit keine Vorlagen direkt aliasieren (wird behoben in 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
}

Es gibt eine weitere Möglichkeit Ich hab's kapiert bei Verwendung von Derived<T>::Nested in Vorlagen, aber auch das ist ein Problem der abhängigen Namen und nicht der Vererbung:

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

Denken Sie nur daran, dass Namen, die von Vorlagenargumenten abhängen, in der

  • mit vorangestelltem typename wenn es sich um einen abhängigen Typ handelt: typename A<T>::B
  • direkt vorangestellt mit template wenn es sich um eine abhängige Vorlage handelt: A<T>::template f<int>()
  • beide, wenn beide: typename A<T>::template B<int>
  • typename ist in Basis-Klassen-Listen unzulässig: template<class T> struct A : B<T>, C<T>::template D<int> {};

3voto

Beta Punkte 91455

Das scheint zu funktionieren:
( EDIT。 einige weitere Zeilen hinzugefügt, um die erste Template-Anweisung zu zeigen. Und danke an Samir Talwar für die Korrektur meiner Formatierung).

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

0voto

coelhudo Punkte 4342

Versuchen Sie dies:

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

Kompiliert gut mit gcc 4.3.3 auf Slackware 13

0voto

Craig Punkte 1159

Ich bin mir immer noch nicht 100%ig sicher, was Sie wollen, aber Sie könnten es versuchen.
Dies kompiliert auf 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;
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X