2015-12-17 1 views
-1

J'ai une classe comme indiqué ci-dessous:instanciation de classe modèle imbriqué

template <class T> 
class outer { 
public: 
    typedef T TType; 
    std::vector <TType> v; 
    int f1 (TType t) {cout << "t= " << t << endl;}; 

    class inner { 
    public: 
    inner& operator=(const inner &in) {return *this;} 
    void f2(const inner &in) {cout << "in f2\n";}  
    }; 
    inner read() {cout << "in read\n";return inner();} 
}; 

extérieur doit avoir niché inner. Je dois créer une classe de base pour outer (Nous revenons en arrière ici !!). Je devrais pouvoir dériver outer1 de la base. Les clients existants de outer devraient fonctionner sans rien changer. outer devrait simplement ajouter du code pour dériver de la classe de base.

Ma solution est:

template <typename T> 
class outer_iface { 
public: 
    typedef T TType; 
    std::vector <TType> v; 
    virtual int f1(TType t) {cout << "bt= " << t << endl;}; 

    template <typename U> 
    class inner_iface { 
    public: 
    using value_type = U; 
    inner_iface& operator=(const inner_iface &in) 
    { 
     return static_cast <U*> (this)->operator=(in); 
    } 
    void f2(const inner_iface &in) 
    { 
     return static_cast <U*> (this)->f2(in); 
    } 
    }; //inner_biface 

    /*template <typename U> 
    typename inner_iface <U>::value_type read() 
    { 
    return static_cast <U*> (this)->read(); 
    }*/ 
}; 

template <typename T> 
class outer : public outer_iface <T> { 
public: 
    typedef T TType; 
    std::vector <TType> v; 
    int f1 (TType t) {cout << "t= " << t << endl;}; 

    class inner : public outer_iface <T> :: template inner_iface <inner> { 
    public: 
    inner& operator=(const inner &in) {return *this;} 
    void f2(const inner &in) {cout << "in f2\n";}  
}; 
inner read() {cout << "in read\n";return inner();} 
}; 

Ceci compile et construit. Mais, j'ai 2 questions:

  1. est ma déclaration/définition read correcte outer_iface?
  2. comment puis-je instancier un outer_iface, avec le type int, et appeler read?
  3. J'ai essayé de main():

    outer_iface<int> oi; 
    oi.read(); 
    

clang a donné des erreurs:

g++ -g --std=c++11 test7.cpp 
test7.cpp: In function ‘int main()’: 
test7.cpp:62:11: error: no matching function for call to  
‘outer_iface<int>::read()’oi.read(); 
           ^
test7.cpp:62:11: note: candidate is: 
test7.cpp:28:40: note: template<class U> typename  
outer_iface<T>::inner_iface<U>::value_type outer_iface<T>::read() 
[with U = U; T = int] 
typename inner_iface <U>::value_type read() 
           ^
test7.cpp:28:40: note: template argument deduction/substitution failed: 
test7.cpp:62:11: note: couldn't deduce template parameter ‘U’ 
oi.read(); 

Alors, évidemment, je ne l'ai pas droit. Comment puis-je corriger inner_face::read? Toute aide/compréhension est appréciée. grâce sdp

+0

Qu'est-ce que "outer1"? * S'il vous plaît * ne pas utiliser des noms extrêmement confus comme "verylongname" et "very1ongname" et "veryIongname1". Pouvons-nous simplement avoir "Foo" et "Bar"? –

+0

Pourquoi introduire CRTP pour 'inner'? – Jarod42

Répondre

0

Il semble que vous voulez quelque chose comme:

template <typename T> 
class outer_iface { 
public: 
    // ... 

    typename T::inner read() 
    { 
     // std::cout << "in read\n"; return typename T::inner(); 
     return static_cast<T*>(this)->read(); 
    } 
}; 
+0

Jarod42, pour tester votre suggestion, j'ai ajouté une classe 'Foo :: inner_face, et dans main do outer_face oi. Cela donne une erreur: g ++ -g --std = C++ 11 test7.cpp test7.cpp: Dans l'instanciation de 'typename T :: inner_iface outer_iface :: read() [avec T = Foo; typename T :: inner_iface = Foo :: inner_iface] ': test7.cpp: 75: 11: requis à partir d'ici test7.cpp: 34: 33: erreur: static_cast invalide du type' outer_iface * const 'to type' Foo * ' return static_cast (this) -> read() ' – sdp

+0

@sdp: oups, mal lu, même si' T' étaient CRTP comme pour interne ... Pouvez-vous ajouter un argument template à 'outer_iface' pour obtenir' outer' et donc 'outer :: inner'? – Jarod42

+0

Désolé, je n'ai pas vraiment compris. Le problème est la déclaration de 'outer_iface :: read()' qui devrait renvoyer un 'inner_iface'. Si vous pouviez donner un extrait, cela m'aiderait à comprendre. – sdp