Можно ли иметь общий, не специализированный член stati c в шаблоне класса в C ++? - PullRequest
2 голосов
/ 27 марта 2020

Допустим, у меня есть шаблон класса, который я хочу создать в соответствии с переменной в загруженном мной файле конфигурации json. В этом файле json переменная может сказать: "TYPEA" или "TYPEB".

Кроме того, у меня есть enum, в котором хранятся все возможные типы, так что я могу переключить регистр, чтобы определить ту или иную специализацию. Теперь мне нужен std :: map, который соотносит это перечисление с соответствующим значением в файле конфигурации, например: {"TYPEA" = TYPEA, "TYPEB" = TYPEB}.

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

Все это означает, что у меня есть static std::map, общий для всех специализаций. Это возможно, или это глупый способ сделать это? Должен ли он быть определен в заголовке или в файле tpp? Проблема с определением карты.

#include <iostream>
#include <map>

template <typename T>
class A
{
    public:

        T m_t;
        enum classType{TYPEA, TYPEB, TYPEC};
        static std::map<std::string, classType> m_typeMap;
        classType m_type;

        A(T& t) : m_t(t) {}
};


template <typename T>
std::map<std::string, A<T>::classType> A<T>::m_typeMap =   // here I get the error
{{"TYPEA", A::classType::TYPEA},
 {"TYPEB", A::classType::TYPEB},
 {"TYPEC", A::classType::TYPEC}};


int main()
{
    std::cout << A::m_typeMap["TYPEA"] << std::endl;
}

Ошибка компилятора:

../main.cpp:19:38: error: type/value mismatch at argument 2 in template parameter list for 'template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map'
 std::map<std::string, A<T>::classType> A<T>::m_typeMap =
                                      ^
../main.cpp:19:38: note:   expected a type, got 'A<T>::classType'
../main.cpp:19:38: error: template argument 4 is invalid
../main.cpp:19:46: error: conflicting declaration 'int A<T>::m_typeMap'
 std::map<std::string, A<T>::classType> A<T>::m_typeMap =
                                              ^~~~~~~~~
../main.cpp:11:49: note: previous declaration as 'std::map<std::__cxx11::basic_string<char>, A<T>::classType> A<T>::m_typeMap'
         static std::map<std::string, classType> m_typeMap;
                                                 ^~~~~~~~~
../main.cpp:19:46: error: declaration of 'std::map<std::__cxx11::basic_string<char>, A<T>::classType> A<T>::m_typeMap' outside of class is not definition [-fpermissive]
 std::map<std::string, A<T>::classType> A<T>::m_typeMap =
                                              ^~~~~~~~~
../main.cpp: In function 'int main()':
../main.cpp:27:18: error: 'template<class T> class A' used without template parameters
     std::cout << A::m_typeMap["TYPEA"] << std::endl;

1 Ответ

3 голосов
/ 27 марта 2020

Возможно ли иметь общий, не специализированный член stati c в шаблонном классе в C ++?

Сделать этот "шаблон класса", и это станет легче понять, что это на самом деле.

Это, конечно, возможно, если вы сделаете шаблон класса наследуемым от общей базы.

struct base { // non-template base
    // static functions and variables 
};

template<typename T>
class Foo : public base {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...