在 C++ 中的 class 模板中是否可以有一个通用的、非专用的静态成员?
Is it possible to have a common, not-specialized, static member in a class template in C++?
假设我有一个 class 模板,我想根据已加载的 json 配置文件中的变量对其进行实例化。在那个 json 文件中,一个变量会说:"TYPEA"
或 "TYPEB"
.
此外,我有一个存储所有可能类型的枚举,因此我可以切换大小写以实例化一种或另一种专业化。现在我需要一个 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;
Is it possible to have a common, not-specialized, static member in a template class in C++?
使之成为 "class template",这样就更容易理解它到底是什么了。
如果您使 class 模板继承自公共基础,那当然是可能的。
struct base { // non-template base
// static functions and variables
};
template<typename T>
class Foo : public base {}
假设我有一个 class 模板,我想根据已加载的 json 配置文件中的变量对其进行实例化。在那个 json 文件中,一个变量会说:"TYPEA"
或 "TYPEB"
.
此外,我有一个存储所有可能类型的枚举,因此我可以切换大小写以实例化一种或另一种专业化。现在我需要一个 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;
Is it possible to have a common, not-specialized, static member in a template class in C++?
使之成为 "class template",这样就更容易理解它到底是什么了。
如果您使 class 模板继承自公共基础,那当然是可能的。
struct base { // non-template base
// static functions and variables
};
template<typename T>
class Foo : public base {}