2012-08-13 117 views
1

我正在使用libMesh FEM庫並試圖開發從libMesh繼承的類(EqCore)。這個類將提供一些額外的功能,這些功能是由我想實際使用的類(MainEq)再次繼承的。C++訪問繼承類的成員,其中繼承的類是模板參數

兩個函數set_constant和get_constant正在導致下面的錯誤。這些工作如不同的繼承方案所示(見Inheritance of template class with a template member function in C++)。與這個問題的區別在於現在模板參數(Type)實際上是一個繼承的類。這是一種危險的做法嗎?

我希望得到這個代碼工作或尋找替代方法的任何幫助。

錯誤信息:

In member function ‘void EqCore::set_constant(std::string, ParamType)’: test_libmesh.cpp:26:57: error: expected primary-expression before ‘>’ token

In member function ‘ParamType EqCore::get_constant(std::string)’: /home/slaughter/Documents/programs/source/test_libmesh.cpp:31:76: error: expected primary-expression before ‘>’ token

方案:

//! \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 : Type{ 
    public: 

     // Class constructor 
     EqCore(EquationSystems& sys, string name) : Type(sys, name, 1){} 

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

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

// A test class derived 
class MainEq : public EqCore<ExplicitSystem>{ 
    public: 

     // Constructor 
     MainEq(EquationSystems& sys) : EqCore(sys, "main"){ } 

}; 


// 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 my class set/get functions 
    MainEq eq(eq_sys); 
    eq.set_constant<double>("test2", 2); 
    printf("Test 2: %f\n", eq.get_constant<double>("test2")); 
} 
+1

Try'Type :: get_equ ation_systems()。parameters.template設置(名稱)' – 2012-08-13 20:06:38

+0

謝謝,這沒有把戲。 – slaughter98 2012-08-13 20:20:14

回答

6

因爲你是一個模板中,編譯器不能確定set在分析時是一個模板自動,它的假設set是一個非模板,因此解析失敗。

解決方案是明確告知編譯器set是一個成員模板,因此。

Type::get_equation_systems().parameters.template set<ParamType>(name) = var

+0

謝謝。我試着把「模板」放到所有的位置,但從來沒有想過把它直接放在設置/得到的單詞前面。謝謝! – slaughter98 2012-08-13 20:18:39

2

C++模板元編程:概念,工具,從升壓和超越,技術由David亞伯拉罕,阿列克謝Gurtovoy(Amazon)它被解釋如下:

double const pi = 3.14159265359; 

template <class T> 
int f(T& x) 
{ 
    return x.convert<3>(pi); 
} 

T::convert might be a member function template, in which case the highlighted code passes pi to a specialization of convert<3> . It could also turn out to be a data member, in which case f returns (x.convert < 3) > pi . That isn't a very useful calculation, but the compiler doesn't know it.

The template keyword tells the compiler that a dependent name is a member template:

template <class T> 
int f(T& x) 
{ 
    return x.template convert<3>(pi); 
} 

If we omit template , the compiler assumes that x.convert does not name a template, and the < that follows it is parsed as the less-than operator.