繁体   English   中英

具有键的std :: map与枚举成员作为模板结构

[英]std::map with key as templated structs with enum member

我想让我的应用程序的std::map的键不是int ,而是更强地键入为模板化的非类型enum ,该enum定义为struct的成员。 下面的第一个程序显示了我的应用当前如何使用map的概念。 它可以编译并正常运行。

#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为类型,而不是值。 为此,请将“枚举”更改为“类型名”:

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;
};

但是,这允许使用非枚举类型。 如果要防止对枚举类型使用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;
};

然后,如果将非枚举作为模板参数传递,则不会编译。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM