【问题标题】:C++ access to members of an inherited class, where the inherited class is a template parameterC++ 访问继承类的成员,其中继承类是模板参数
【发布时间】:2012-08-13 20:03:20
【问题描述】:

我正在使用 libMesh FEM 库并尝试开发一个继承自 libMesh 的类 (EqCore)。这个类将提供一些额外的特性,这些特性被我想要实际使用的类(MainEq)再次继承。

set_constant 和 get_constant 这两个函数导致以下错误。它们使用不同的继承方案如图所示工作(参见Inheritance of template class with a template member function in C++)。这个问题的不同之处在于,现在模板参数(Type)实际上是一个被继承的类。这是一种危险的做法吗?

如果您能帮我解决此代码或寻找替代方法,我将不胜感激。

错误消息:

在成员函数‘void EqCore::set_constant(std::string, ParamType)’中: test_libmesh.cpp:26:57:错误:“>”标记之前的预期主表达式

在成员函数‘ParamType EqCore::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"));   
}

【问题讨论】:

  • 试试Type::get_equation_systems().parameters.template set&lt;ParamType&gt;(name)

标签: c++ templates inheritance disambiguation


【解决方案1】:

因为你在一个模板里面,编译器在解析的时候不能自动判断set是一个模板,它假设set是一个非模板,因此解析失败。

解决方案是明确告知编译器set 是一个成员模板。

Type::get_equation_systems().parameters.template set&lt;ParamType&gt;(name) = var

【讨论】:

  • 谢谢。我尝试将“模板”放在各处,但从未想过将其直接放在 set/get 单词的前面。谢谢!
【解决方案2】:

C++ 模板元编程:Boost 及其他领域的概念、工具和技术,由 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&lt;3&gt; 的特化。它 也可能成为数据成员,在这种情况下 f 返回 (x.convert &lt; 3 ) &gt; pi。这不是一个非常有用的计算,但是 编译器不知道。

template 关键字告诉编译器依赖名称是 成员模板:

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

如果我们省略template,编译器会假定x.convert 没有 命名一个模板,它后面的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多