2008-11-05 5 views
2

J'essaye de créer une classe de modèle pour isoler les utilisateurs d'un type de données. J'aurais préféré utiliser une classe d'adaptateur, mais les signatures de fonction ont besoin de changer nécessitant un modèle.Modèles imbriqués gcc compilateur 4.1.2 erreur

Dans l'exemple de code ci-dessous (pas le projet actuel juste une version simplifiée pour illustrer le problème), alors que dans la routine principale, je suis capable d'utiliser l'interface ob_traits. Mais lorsque je tente de créer le StructWrapper structuré qui utilise ob_traits comme classe de base, j'obtiens des erreurs et gcc ne reconnaît pas la classe IntAdapter créée. Cela compile sur MSVC 8.0 mais échoue sur gcc 4.1.2 20070626 (Red Hat 4.1.2-14)

Donc, deux questions d'abord, comprenez-vous pourquoi la compilation échoue avec les erreurs spécifiées ci-dessous? Deuxièmement, des suggestions sur la façon de mettre en œuvre ce concept d'une manière plus simple?

#include <iostream> 

    template <typename T > 
    struct ob_traits 
    { 
     ob_traits(T& param) { value = param; }; 
     T value; 
    }; 

    struct GeneralStructure 
    { 
     int a; 
     GeneralStructure(int param):a(param){} 
    }; 

    struct DifferentStructure 
    { 
     GeneralStructure hidden; 
     DifferentStructure(int param):hidden(param){}; 
    } 
    ; 

    /*template< typename T > struct ob_traits 
    { 
    }; 
    */ 
    template<> struct ob_traits<GeneralStructure> 
    { 
     struct IntAdapter 
     { 
      IntAdapter(GeneralStructure& valueParam):value(valueParam){} 
      GeneralStructure value; 
      int& getValue() { return value.a; }; 
     }; 
    }; 

    template<> struct ob_traits<DifferentStructure> 
    { 
     struct IntAdapter 
     { 
      IntAdapter(DifferentStructure& valueParam):value(valueParam){} 
      DifferentStructure value; 
      int& getValue(){ return value.hidden.a; }; 
     }; 
     void dump() 
     { 
      DifferentStructure testLocal(44); 
      IntAdapter local(testLocal); 
      std::cout << local.getValue()<<std::endl; 
     } 
    }; 

    template <typename T > struct StructWrapper:public ob_traits<T> 
    { 
     StructWrapper(){}; 
    /*main.cpp:60: error: 'IntAdapter' was not declared in this scope 
    main.cpp:60: error: expected `;' before 'inner' 
    main.cpp:60: error: 'inner' was not declared in this scope 
    */ 
     void dumpOuter(const T& tempParam) { IntAdapter inner(tempParam); inner.dump(); }; 
    /* 
    main.cpp: In member function 'void StructWrapper<T>::dumpOuterFailsAsWell(const T&)': 
    main.cpp:66: error: expected `;' before 'inner' 
    main.cpp:66: error: 'inner' was not declared in this scope 
    */ 
     void dumpOuterFailsAsWell(const T& tempParam) { ob_traits<T>::IntAdapter inner(tempParam); inner.dump(); }; 
    }; 

    int main(int argc, char* argv[]) 
    { 
     GeneralStructure dummyGeneral(22); 
     ob_traits<struct GeneralStructure >::IntAdapter test(dummyGeneral); 
     DifferentStructure dummyDifferent(33); 
     ob_traits<struct DifferentStructure >::IntAdapter test2(dummyDifferent); 
     std::cout << "GeneralStructure: "<<test.getValue()<<std::endl; 
     std::cout << "DifferentStructure: "<<test2.getValue()<<std::endl; 
     ob_traits<struct DifferentStructure > test3; 
     test3.dump(); 
    std::cout << "Test Templated\n"; 
    return 0; 
    } 
+0

résolution a été trouvée en mettant à jour les deux lignes: vide dumpOuterFailsAsWell (const T & tempParam) { 'typename' ob_traits :: IntAdapter intérieure (tempParam); inner.dump(); } }; –

+0

Problème similaire avec une explication plus concise à: http://stackoverflow.com/questions/11405/template-problem-with-gcc – Superpolock

Répondre

0

StructWrapper hérite à partir du modèle de classe primaire (le moins spécialisé), qui ne définit pas IntWrapper, donc il ne peut pas être utilisé dans cette classe. Je ne suis pas sûr si l'instanciation d'un StructWrapper avec l'un des types plus spécialisés lui permettra de fonctionner, ou s'il échoue à compiler la définition de classe elle-même.

0

La compilation échoue car IntAdapter n'apparaît que dans le modèle spécialisé et n'est donc pas visible au point de référence.

Pas clair pour quoi l'utiliseriez-vous? S'il vous plaît clarifier les circonstances.

+0

Je pensais que cela devrait fonctionner parce que IntAdapter est héritée publiquement dans la classe dérivée. Je suis confus pourquoi les compilations StructWrapper échouent. Je souhaite créer un adaptateur basé sur le paramètre basé sur un modèle et utiliser cet adaptateur pour accéder aux composants de la classe. De meilleures suggestions? –

2

dumpOuter échoue car IntAdapter doit être qualifié (comme dans la question référencée). dumpOuterFailsAsWell échoue parce que GCC n'analyse de ce code, même si ce n'est pas complète, et donc il a besoin de savoir qu'il est un type que vous voulez dire:

void dumpOuterWorks(const T& tempParam) 
{ 
    typename ob_traits<T>::IntAdapter inner(tempParam); 
    inner.dump(); 
} 

Sans typename ici, GCC supposerons que IntAdapter est un identifiant et vous attendre à former une expression plutôt qu'une déclaration de variable.

Notez également que vous n'avez pas besoin de mettre des points-virgules après les corps de méthode!

Questions connexes