2012-06-14 11 views
5

Domanda: Ho ricevuto il seguente errore per il seguente codice, qualcuno sa perché?Ereditarietà della classe template con una funzione membro template in C++

Problema: Sto lavorando su una classe (ClassB) che controlla il comportamento di un certo numero di classi da una libreria esterna (libMesh). La parte "... fa qualcosa ... del codice è progettata per impostare alcune variabili in queste classi di libreria esterne che hanno funzioni di modello

Vorrei poter impostare alcuni di questi valori dal costruttore di la classe ereditaria (ClassC) .Ma se faccio questo, come nel codice qui sotto, visualizzo l'errore mostrato.Se tolgo questo comando nel costruttore funziona perfettamente.

Includo anche un esempio più dettagliato che usa che produce lo stesso errore, ma usa la stessa classe libmesh, illustra ciò che voglio fare un po 'meglio. Non sono sicuro dell'utilità di quello che sto cercando di fare, voglio soprattutto sapere perché questo non lavoro perché sembra che dovrebbe.

Ho trovato un altro post simile, ma non riesco ad applicarli al mio problema.

Template inheritance inner class access problem

Grazie per l'aiuto, Andrew

ERRORE:

[email protected]:~/Documents/programs/build$ make test 
[100%] Building CXX object CMakeFiles/test.dir/source/test.cpp.o 
test.cpp: In constructor ‘ClassC<T>::ClassC()’: 
test.cpp:16:29: error: expected primary-expression before ‘int’ 
test.cpp:16:29: error: expected ‘;’ before ‘int’ 
make[3]: *** [CMakeFiles/test.dir/source/test.cpp.o] Error 1 
make[2]: *** [CMakeFiles/test.dir/all] Error 2 
make[1]: *** [CMakeFiles/test.dir/rule] Error 2 
make: *** [test] Error 2 

codice semplice:

// A class that sets that sets the value of something 
template <typename Type> class ClassB{ 
public: 
    ClassB(){} 
    template<typename TypeValue> void set_value(TypeValue value){ 
     // ... do something ... 
    } 
}; 

// A class that inherits ClassB 
template<typename T> class ClassC : public ClassB<T>{ 
public: 
    ClassC(){ 
     // I want to do this (if I remove this it compiles) 
     ClassB<T>::set_value<int>(1);; 
    } 
}; 

// The main function 
int main(){ 
    ClassC<double> c; 
    c.set_value<int>(1); // This works 
} 

problema specifico CODICE:

01.235.
//! \example test_libmesh.cpp 

#include <string> 
using std::string; 

// libMesh includes 
#include <libmesh.h> 
#include <libmesh_common.h> 
#include <equation_systems.h> 
#include <transient_system.h> 
#include <explicit_system.h> 
#include <parameters.h> 
#include <mesh.h> 
using namespace libMesh; 

// Fundamental behavior that will be used among many classes 
template <typename Type> class EqCore{ 
    public: 

     // Class constructor 
     EqCore(EquationSystems& sys, string name) : eq_sys(sys){ 

      // Creates a system that will store the constant(s) 
      name_.assign(name); 
      eq_sys.add_system<Type>(name_); 

      // I can set stuff from here 
      set_constant<double>("test4", 4); 
     } 

     // A function for storing a constant value 
     template<typename ParamType> void set_constant(std::string name, ParamType var){ 
      eq_sys.parameters.set<ParamType>(name) = var; 
     } 

     // A function for retrieving a constant value 
     template<typename ParamType> ParamType get_constant(std::string name){ 
      ParamType output = eq_sys.parameters.get<ParamType>(name); 
      return output; 
     } 

     // Reference to the controlling equation system 
     EquationSystems& eq_sys;  

     // The name of the system holding the constant(s) 
     string name_; 
}; 

// A test class derived 
template <typename Type> class EqBase : public EqCore<Type>{ 
    public: 

     // Constructor 
     EqBase(EquationSystems& sys, string name) : EqCore<Type>(sys, name){  

      // I want to do this! 
      // (remove this and the associated print statement in the main and it works) 
      EqCore<Type>::set_constant<double>("test5", 5); 
     } 

}; 

// Begin main function 
int main (int argc, char** argv){ 

    // Initialize libMesh and create an empty mesh 
    LibMeshInit init (argc, argv); 
    Mesh mesh; 

    // Test w/o any of the above classes 
    EquationSystems eq_sys(mesh); 
    eq_sys.parameters.set<double>("test1") = 1; 
    printf("Test 1: %f\n", eq_sys.parameters.get<double>("test1")); 

    // Test EqBase/EqCore functions set/get functions 
    EqBase<TransientExplicitSystem> eq(eq_sys, "TestSystem"); 
    eq.set_constant<double>("test2", 2); 
    printf("Test 2: %f\n", eq.get_constant<double>("test2")); 

    // Test generic creation but accessed through EqBase 
    eq.eq_sys.parameters.set<double>("test3") = 3; 
    printf("Test 3: %f\n", eq.eq_sys.parameters.get<double>("test3")); 

    // Test the constant created in EqCore constructor from EqBase 
    printf("Test 4: %f\n", eq.eq_sys.parameters.get<double>("test4")); 

    // Test the constant created in EqBase constructor from EqBase 
    printf("Test 5: %f\n", eq.eq_sys.parameters.get<double>("test5")); 

} 

risposta

3

Il compilatore non riesce a capire come analizzare questa cosa perché non riesce a capire che set_value è il nome di un modello. Se si aggiunge la parola chiave template dopo la :: si risolve il problema:

ClassC(){ 
    // I want to do this (if I remove this it compiles) 
    ClassB<T>::template set_value<int>(1);; 
} 

La risposta a questa domanda va in grande dettaglio circa perché: Where and why do I have to put the "template" and "typename" keywords?

+0

Grazie, così semplice. – slaughter98

Problemi correlati