Inheritance of template class with a template member function in C++
c++, inheritance, templates
Solution
The compiler can't work out how to parse this thing because it can't work out that set_value is the name of a template. If you add the keyword `template` after the `::` it fixes the problem:
ClassC(){
// I want to do this (if I remove this it compiles)
ClassB<T>::template set_value<int>(1);;
}
The answer to this question goes into great detail about why: Where and why do I have to put the "template" and "typename" keywords?
Problem
Question: I receive the following error for the code below, does anyone know why? Problem: I am working on a class (ClassB) that controls the behavior of a number of classes from an outside library (libMesh). The "...do something... portion of the code is designed to set some variables in these outside library classes that have template functions. I would like to be able to set some of these values from the constructor of the inheriting class (ClassC). But, if I do this, as in the code below, I get the error shown. If I remove this command in the constructor it works just fine. I also include a more detailed example that uses that produces the same error, but uses the libmesh class itself, it illustrates what I want to do a bit better. I am unsure of the usefulness of what I am trying to do, I mainly want to know why this doesn't work because it seems like it should. I found one other similar post, but I can't seem to apply them to my problem. Template inheritance inner class access problem Thanks for the help, Andrew ERROR: ``` XXXXXXX@XXXXX:~/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 } ``` PROBLEM SPECIFIC CODE: ``` //! \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")); } ```