std::map 键作为带有枚举成员的模板化结构
std::map with key as templated structs with enum member
我想让我的应用程序的 std::map
s 的键不是 int
s,而是更强烈地类型化为定义为成员的模板化非类型 enum
s的 struct
。下面的第一个程序显示了我的应用程序当前如何使用 map
s 的概念。它编译并运行正常。
#include <map>
template< int >
struct NummedMap
{
typedef std::map< int, NummedMap > NumableMap;
NummedMap() {}
NumableMap numableMap;
};
int main()
{
NummedMap< 3 > numableMap3;
NummedMap< 4 > numableMap4;
numableMap3.numableMap[ 3 ] = numableMap3;
numableMap4.numableMap[ 4 ] = numableMap4;
return 0;
}
第二个程序展示了我想如何对我的应用程序的 map
进行编程,但是我遗漏了一些关于非类型模板的概念以及为什么 < enum EnumT >
不同于 POD int
.
#include <map>
struct Enums1 // a struct containing one kind scoped enums
{
enum class Action
{
AAAA,
BBBB
};
};
struct Enums2 // a struct containing another kind scoped enums
{
enum class Action
{
CCCC,
DDDD
};
};
template< enum EnumT >
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap; // error C2065: 'EnumT': undeclared identifier
EnummedMap() {}
EnumableMap enumableMap;
};
int main()
{
EnummedMap< Enums1::Action > enummedMap1; // error C2993: illegal type for non-type template parameter
EnummedMap< Enums2::Action > enummedMap2; // error C2993: illegal type for non-type template parameter
enummedMap1.enumableMap[ Enums1::Action::AAAA ] = enummedMap1; // error C2678: binary '[': no operator found which takes a left-hand operand of type
enummedMap2.enumableMap[ Enums2::Action::CCCC ] = enummedMap2; // error C2678: binary '[': no operator found which takes a left-hand operand of type
return 0;
}
我不明白为什么 EnumableMap
的密钥未声明,或者为什么 Enums1::Action
的功能不像 int
密钥。
template< enum EnumT >
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap;
非类型模板参数(在本例中为旧式枚举)是单个值,根据定义不是类型,但 std::map 期望 Key 是类型,而不是一个值。要使其工作,请将 "enum" 更改为 "typename":
template<typename EnumT > // << *** HERE ***
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap;
EnummedMap() {}
EnumableMap enumableMap;
};
但是,这允许非枚举类型。如果你想防止除了枚举类型之外的所有使用,你可以使用 static_assert:
#include <type_traits>
//...
template<typename EnumT>
struct EnummedMap
{
static_assert(std::is_enum_v<EnumT>); // c++17
//static_assert(std::is_enum<EnumT>::value, ""); // c++11
typedef std::map< EnumT, EnummedMap > EnumableMap;
EnummedMap() {}
EnumableMap enumableMap;
};
然后如果一个非枚举作为模板参数传递,它将不会编译。
我想让我的应用程序的 std::map
s 的键不是 int
s,而是更强烈地类型化为定义为成员的模板化非类型 enum
s的 struct
。下面的第一个程序显示了我的应用程序当前如何使用 map
s 的概念。它编译并运行正常。
#include <map>
template< int >
struct NummedMap
{
typedef std::map< int, NummedMap > NumableMap;
NummedMap() {}
NumableMap numableMap;
};
int main()
{
NummedMap< 3 > numableMap3;
NummedMap< 4 > numableMap4;
numableMap3.numableMap[ 3 ] = numableMap3;
numableMap4.numableMap[ 4 ] = numableMap4;
return 0;
}
第二个程序展示了我想如何对我的应用程序的 map
进行编程,但是我遗漏了一些关于非类型模板的概念以及为什么 < enum EnumT >
不同于 POD int
.
#include <map>
struct Enums1 // a struct containing one kind scoped enums
{
enum class Action
{
AAAA,
BBBB
};
};
struct Enums2 // a struct containing another kind scoped enums
{
enum class Action
{
CCCC,
DDDD
};
};
template< enum EnumT >
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap; // error C2065: 'EnumT': undeclared identifier
EnummedMap() {}
EnumableMap enumableMap;
};
int main()
{
EnummedMap< Enums1::Action > enummedMap1; // error C2993: illegal type for non-type template parameter
EnummedMap< Enums2::Action > enummedMap2; // error C2993: illegal type for non-type template parameter
enummedMap1.enumableMap[ Enums1::Action::AAAA ] = enummedMap1; // error C2678: binary '[': no operator found which takes a left-hand operand of type
enummedMap2.enumableMap[ Enums2::Action::CCCC ] = enummedMap2; // error C2678: binary '[': no operator found which takes a left-hand operand of type
return 0;
}
我不明白为什么 EnumableMap
的密钥未声明,或者为什么 Enums1::Action
的功能不像 int
密钥。
template< enum EnumT >
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap;
非类型模板参数(在本例中为旧式枚举)是单个值,根据定义不是类型,但 std::map 期望 Key 是类型,而不是一个值。要使其工作,请将 "enum" 更改为 "typename":
template<typename EnumT > // << *** HERE ***
struct EnummedMap // a struct containing a map whose key is non-type templateable
{
typedef std::map< EnumT, EnummedMap > EnumableMap;
EnummedMap() {}
EnumableMap enumableMap;
};
但是,这允许非枚举类型。如果你想防止除了枚举类型之外的所有使用,你可以使用 static_assert:
#include <type_traits>
//...
template<typename EnumT>
struct EnummedMap
{
static_assert(std::is_enum_v<EnumT>); // c++17
//static_assert(std::is_enum<EnumT>::value, ""); // c++11
typedef std::map< EnumT, EnummedMap > EnumableMap;
EnummedMap() {}
EnumableMap enumableMap;
};
然后如果一个非枚举作为模板参数传递,它将不会编译。