c++ - std::map with key as templated structs with enum member

标签 c++ templates enums stdmap non-type

我想让我的应用程序的 std::map s 的键不是 int s,而是更强烈地类型化为模板化非类型 enum s 定义为 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 进行编程s,但我缺少一些关于非类型模板的概念以及为什么 < 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的 key 未声明,或者为什么例如 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;
};

但是,这允许非枚举类型。如果你想阻止枚举类型的所有使用 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;
};

如果将非枚举作为模板参数传递,它将无法编译。

关于c++ - std::map with key as templated structs with enum member,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45336004/

相关文章:

c++ - VC++ 2012 中出乎意料的模棱两可的重载解析

c++ - 错误说定义为公共(public)的类是私有(private)的

c++ - 如何将模板类容器的迭代器传递给函数?

c++ - 从同一类的两个不同模板拷贝继承时重载

visual-studio-2013 - 如何在定义文件中引用 Typescript 枚举

c++ - 如何将基类的枚举传递给子类的构造函数

java - 声明要在数组中使用的枚举?

c# - 将 C 定义宏转换为 C#

templates - Dojo 和模板解决方案

c++ - 开罗:裁剪 PDF 表面?