[英]How to declare a std::map from EnumType to EnumTypeValue?
I have an enum:我有一个枚举:
enum VehicleType {CAR, BIKE, TRUCK};
The following class uses this enum as a template parameter:以下 class 使用此枚举作为模板参数:
template <VehicleType V>
class ParkingSlotContainer
{
...
};
Now, I wish to define a class with a map data member that maps a VehicleType
to ParkingSlotContainer<VehicleType>
.现在,我希望定义一个 class 和一个 map 数据成员,将
VehicleType
映射到ParkingSlotContainer<VehicleType>
。 In other words, I want to map CAR
to ParkingSlotContainer<CAR>
, BIKE
to ParkingSlotContainer<BIKE>
, etc.换句话说,我想要 map
CAR
到ParkingSlotContainer<CAR>
, BIKE
到ParkingSlotContainer<BIKE>
等。
This is my attempt:这是我的尝试:
class ParkingFloor
{
private:
int floor;
map<VehicleType, ParkingSlotContainer<VehicleType> > slots;
public:
ParkingFloor(...);
...
};
The compiler doesn't accept the above and reports that type name is not allowed
.编译器不接受上述内容并报告
type name is not allowed
。 It expects ParkingSlotContainer<CAR|BIKE|TRUCK>
instead of ParkingSlotContainer<VehicleType>
.它需要
ParkingSlotContainer<CAR|BIKE|TRUCK>
而不是ParkingSlotContainer<VehicleType>
。
What is the right way to define such a map?定义这样一个 map 的正确方法是什么?
The problem is that you cannot have two values of different type in an std::map
: For instance, you cannot have both a ParkingSlotContainer<BIKE>
and ParkingSlotContainer<CAR>
inside the slots
variable, because they are different types.问题是您不能在
std::map
中拥有两个不同类型的值:例如,您不能在slots
变量中同时拥有ParkingSlotContainer<BIKE>
和ParkingSlotContainer<CAR>
,因为它们是不同的类型。
For these kinds of situations where you want to produce types from enum values, you may want to use higher order macros .对于这些您想从枚举值生成类型的情况,您可能需要使用更高阶的宏。 Here is an example of higher order macros applied to your code, where we use them to declare three member variables (
_CAR
, _BIKE
and _TRUCK
) for the three enum values and then generate overloaded methods setSlot
to set a new value to any one of them.这是一个应用于您的代码的高阶宏的示例,我们使用它们为三个枚举值声明三个成员变量(
_CAR
、 _BIKE
和_TRUCK
),然后生成重载方法setSlot
以将新值设置为其中任何一个. Just to demonstrate how you can use higher order macros:只是为了演示如何使用高阶宏:
#define FOREACH_VEHICLE_TYPE(OP) \
OP(CAR) \
OP(BIKE) \
OP(TRUCK)
enum VehicleType {
#define DECL_VEHICLE(name) name,
FOREACH_VEHICLE_TYPE(DECL_VEHICLE)
#undef DECL_VEHICLE
};
template <VehicleType V>
class ParkingSlotContainer
{
public:
int vehicleCount = 0;
};
class ParkingFloor
{
private:
int floor;
#define DECL_SLOT(name) ParkingSlotContainer<name> _##name;
FOREACH_VEHICLE_TYPE(DECL_SLOT)
#undef DECL_SLOT
public:
#define SET_SLOT(name) void setSlot(const ParkingSlotContainer<name>& newValue) {_##name = newValue;}
FOREACH_VEHICLE_TYPE(SET_SLOT)
#undef SET_SLOT
};
int main() {
ParkingSlotContainer<BIKE> bikes;
bikes.vehicleCount = 119;
ParkingFloor parkingFloor;
parkingFloor.setSlot(bikes);
return 0;
}
Depending on your application, this may or may not be overkill.根据您的应用程序,这可能会或可能不会矫枉过正。 It sort of makes the code harder to read...
这有点让代码更难阅读......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.