C++ доступ к членам унаследованного класса, где унаследованный класс является параметром шаблона

Я работаю с библиотекой libMesh FEM и пытаюсь разработать класс (EqCore), который наследуется от libMesh. Этот класс предоставит некоторые дополнительные функции, которые снова наследуются классом, который я хочу использовать (MainEq).

Две функции, set_constant и get_constant, вызывают ошибку ниже. Они работали, как показано с другой схемой наследования (см. Наследование шаблонного класса с функцией-членом шаблона в 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"));   
}

2 ответа

Решение

Поскольку вы находитесь внутри шаблона, компилятор не может определить, что set шаблон автоматически во время разбора, и предполагается, что set не является шаблоном, и, следовательно, анализ не выполняется.

Решение состоит в том, чтобы явно сообщить компилятору, что set это шаблон участника, как таковой.

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

В метапрограммировании шаблонов на C++: концепции, инструменты и методы из Boost и Beyond Дэвидом Абрахамсом, Алексеем Гуртовым ( 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 не называет шаблон, и символ<, следующий за ним, анализируется как оператор меньше чем.

Другие вопросы по тегам