簡體   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