2012-06-14 17 views
5

質問:以下のコードで次のエラーが表示されます。なぜですか?C++のテンプレートメンバー関数を使用したテンプレートクラスの継承

問題:私はクラスの外部ライブラリ(libMesh)からクラスの数の動作を制御します(ClassBの)に取り組んでいます 。コードの "... do something ..."部分は、テンプレート関数を持つこれらの外部ライブラリクラスでいくつかの変数を設定するように設計されています。これらの値のいくつかは、次のコンストラクタから設定することができます。継承クラス(ClassC)ですが、下のコードのようにこれを行うとエラーが表示されます。コンストラクタでこのコマンドを削除してもうまくいきます。

さらに詳しい例がありますそれは同じエラーを生成しますが、libmeshクラスそのものを使用していますが、私は少し上手くやりたいことを示しています。私は何をしようとしているのか分かりません。それが必要であるように思われるので、仕事。

私は他の同様の投稿を見つけましたが、私はそれらを私の問題に適用できないようです。助けのための

Template inheritance inner class access problem

おかげで、 アンドリュー

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 
} 

問題固有のコード:

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

} 

答えて

3

コンパイラは、set_valueがテンプレートの名前であるために、このことを解析する方法を理解できません。 Where and why do I have to put the "template" and "typename" keywords?

+0

おかげで、非常にシンプル:

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

この質問への答えは理由について非常に詳細に入る:あなたは::後にキーワードtemplateを追加した場合、それは問題を修正します。 – slaughter98

関連する問題