1

私はlibMeshFEMライブラリを使用しており、libMeshから継承するクラス(EqCore)を開発しようとしています。このクラスは、実際に使用したいクラス(MainEq)によって再び継承されるいくつかの追加機能を提供します。

set_constantとget_constantの2つの関数が原因で、以下のエラーが発生しています。これらは、異なる継承スキームで示されているように機能しました(C ++のテンプレートメンバー関数を使用したテンプレートクラスの継承を参照)。この問題との違いは、テンプレートパラメータ(Type)が実際には継承されるクラスであるということです。これは危険な行為ですか?

このコードを機能させる、または別の方法を見つける手助けをいただければ幸いです。

エラーメッセージ:

メンバー関数で'voidEqCore :: set_constant(std :: string、ParamType)':test_libmesh.cpp:26:57:エラー:'>'トークンの前にプライマリ式が必要です

メンバー関数'ParamTypeEqCore :: get_constant(std :: string)':/home/slaughter/Documents/programs/source/test_libmesh.cpp:31:76:エラー:'>'トークンの前にプライマリ式が必要です

プログラム:

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

2 に答える 2

6

setテンプレートの内部にいるため、コンパイラは解析時にそれがテンプレートであると自動的に判断できず、それsetが非テンプレートであると想定しているため、解析は失敗します。

set解決策は、メンバー テンプレートであることをコンパイラに明示的に通知することです。

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

于 2012-08-13T20:07:09.793 に答える
2

C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyondでは、David Abrahams、Aleksey Gurtovoy ( Amazon ) が次のように説明しています。

double const pi = 3.14159265359;

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

T::convertはメンバ関数テンプレートである可能性があり、その場合、強調表示されたコードはpiの特殊化に渡されconvert<3>ます。また、データ メンバーになることもあり、その場合fは が返さ れます(x.convert < 3 ) > pi。これはあまり有用な計算ではありませんが、コンパイラはそれを知りません。

templateキーワードは、従属名がメンバー テンプレートであることをコンパイラに伝えます。

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

を省略するtemplateと、コンパイラは がx.convertテンプレートに名前を付けていないと見なし、それに続く < は小なり演算子として解析されます。

于 2012-08-13T20:20:22.020 に答える