[英]std::map with key as templated structs with enum member
I would like to make my app's std::map
s' keys not be int
s, but rather be more strongly typed as templated non-type enum
s defined as a member of a struct
. 我想让我的应用程序的std::map
的键不是int
,而是更强地键入为模板化的非类型enum
,该enum
定义为struct
的成员。 The first program below shows the concept of how my app currently uses map
s. 下面的第一个程序显示了我的应用当前如何使用map
的概念。 It compiles and runs ok. 它可以编译并正常运行。
#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;
}
The second program shows how I would like to program my app's map
s, but I am missing some concepts regarding non-type templates and why an < enum EnumT >
is different from a POD int
. 第二个程序显示了我想如何对应用程序的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;
}
I don't understand why EnumableMap
's key is undeclared, or why for example Enums1::Action
does not function roughly like an int
key. 我不明白为什么未声明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;
A non-type template parameter (in this case an old-style enum), is a single value, and by definition is not a type, but std::map expects the Key to be a type, not a value. 非类型模板参数(在本例中为旧式枚举)是单个值,根据定义不是类型,但std :: map期望Key为类型,而不是值。 To make this work, change "enum" to "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;
};
However, this allows for non-enum types. 但是,这允许使用非枚举类型。 If you want to prevent all uses EXCEPT for enum types, you can use a static_assert: 如果要防止对枚举类型使用EXCEPT,可以使用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;
};
Then it won't compile if a non-enum is passed as the template parameter. 然后,如果将非枚举作为模板参数传递,则不会编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.