2012-06-14 24 views
5

Frage: Ich erhalte den folgenden Fehler für den folgenden Code, weiß jemand warum?Vererbung der Vorlagenklasse mit einer Vorlage Elementfunktion in C++

Problem: ich für eine Klasse arbeite (ClassB), die das Verhalten einer Anzahl von Klassen aus einer externen Bibliothek steuert (libMesh). Der Teil "... tue etwas ..." des Codes wurde entwickelt, um einige Variablen in diesen externen Bibliotheksklassen mit Vorlagenfunktionen zu setzen.

Ich möchte einige dieser Werte im Konstruktor von die erbende Klasse (ClassC). Aber, wenn ich dies tun, wie in dem Code unten, bekomme ich den Fehler angezeigt. Wenn ich diesen Befehl im Konstruktor entfernen, funktioniert es ganz gut.

Ich füge auch ein ausführlicheres Beispiel Das verwendet denselben Fehler, benutzt aber die libmesh Klasse selbst, es stellt dar, was ich ein bisschen besser machen will.Ich bin mir nicht sicher über die Nützlichkeit dessen, was ich versuche zu tun, ich möchte hauptsächlich wissen, warum das nicht so ist arbeiten, weil es scheint, wie es sollte

Ich fand einen anderen ähnlichen Beitrag, aber ich kann nicht scheinen, sie auf mein Problem anzuwenden.

Template inheritance inner class access problem

Danke für die Hilfe, Andrew

ERROR:

[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 

SIMPLE Code:

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

spezifischen Code PROBLEM:

//! \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")); 

} 

Antwort

3

Der Compiler kann nicht herausfinden, wie diese Sache zu analysieren ist, weil es nicht herausfinden kann, dass set_value der Name einer Vorlage ist. Wenn Sie das Schlüsselwort template nach den :: hinzufügen behebt es das Problem:

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

Die Antwort auf diese Frage geht sehr ins Detail, warum: Where and why do I have to put the "template" and "typename" keywords?

+0

Danke, so einfach. – slaughter98

Verwandte Themen