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
关键。
答
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;
};
那么如果非枚举作为模板参数传递就不会编译。
你究竟想要达到什么目的? –
在大型程序中'更强类型化'可以转化为更大的程序清晰度,更好的错误检查和更简单的代码维护。 – rtischer8277