std ::地图与键为模板结构与枚举成员

问题描述:

我想使我的应用程序的std::map s'键不是int s,而是更强烈类型为模板非类型enum定义为一个成员struct。下面的第一个程序显示了我的应用程序目前如何使用map s的概念。它编译并运行正常。std ::地图与键为模板结构与枚举成员

#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的关键是未申报的,或者为什么例如Enums1::Action没有大致的功能就像一个int关键。

+0

你究竟想要达到什么目的? –

+0

在大型程序中'更强类型化'可以转化为更大的程序清晰度,更好的错误检查和更简单的代码维护。 – rtischer8277

template< enum EnumT > 
struct EnummedMap // a struct containing a map whose key is non-type templateable 
{ 
    typedef std::map< EnumT, EnummedMap > EnumableMap; 

非类型模板参数(在这种情况下的旧式枚举),是一个单值,顾名思义就是不是一个类型,但性病::地图预计,关键是一个类型,没有价值。要做到这一点,请将“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; 
}; 

那么如果非枚举作为模板参数传递就不会编译。