有没有办法将枚举值映射到C ++中的类型,包括C ++ 11 我有以下枚举类型:
enum ATTRIBUTE{AGE=0, MENOPAUSE, TUMOR_SIZE, INV_NODES, NODE_CAPS,
DEG_MALIG, BREAST, BREAST_QUAD, IRRADIAT, CLASS};
我想将此枚举的每个值映射到某种类型。我想将AGE
映射到int
,将MENOPAUSE
映射到另一个枚举类型,将BREAST
映射到bool,依此类推。
那么是否可以创建一个返回类型值的函数,该值取决于attr变量的值?
//Like that:
auto value = map_attr(ATTRIBUTE attr);
//Here the type of the value variable should be int if the attr variable is AGE, bool for BREAST and so on.
答案 0 :(得分:10)
这种惯用方法是使用特征:
enum ATTRIBUTE{ AGE=0, MENOPAUSE, TUMOR_SIZE, INV_NODES, NODE_CAPS, DEG_MALIG, BREAST, BREAST_QUAD, IRRADIAT, CLASS };
template<ATTRIBUTE> struct Map;
template<> struct Map<AGE> {
using type = int;
static constexpr type value = 42;
};
template<> struct Map<MENOPAUSE> {
using type = AnotherEnumType;
static constexpr type value = AnotherEnumType::AnotherEnumValue;
};
// ...
然后您可以将map_attr
定义为函数模板:
template<ATTRIBUTE A>
typename Map<A>::type map_attr() { return Map<A>::value; }
并将其用作:
auto something = map_attr<AGE>();
它遵循一个最小的工作示例:
#include<type_traits>
enum ATTRIBUTE{ AGE=0, MENOPAUSE };
template<ATTRIBUTE> struct Map;
template<> struct Map<AGE> {
using type = int;
static constexpr type value = 42;
};
template<> struct Map<MENOPAUSE> {
using type = double;
static constexpr type value = 0.;
};
template<ATTRIBUTE A>
typename Map<A>::type map_attr() { return Map<A>::value; }
int main() {
static_assert(std::is_same<decltype(map_attr<AGE>()), int>::value, "!");
static_assert(std::is_same<decltype(map_attr<MENOPAUSE>()), double>::value, "!");
}
答案 1 :(得分:0)
我使用 vector<void*>
尝试了 skypjack's answer 中的方法,以更好地理解它:
#include <iostream>
#include <vector>
using namespace std;
enum Types
{
Int,
Double
};
//Use struct instead of class for auto-public.
template<Types> struct TypesMap;
template<> struct TypesMap<Int>
{
using type = int;
};
template<> struct TypesMap<Double>
{
using type = double;
};
int main() {
std::vector<void*> Test;
//Note: Memory leak here, but just as an example.
Test.push_back(new TypesMap<Int>::type(0.5));
Test.push_back(new TypesMap<Double>::type(0.5));
std::cout << *((TypesMap<Int>::type*)Test[0]) << " " << *((TypesMap<Double>::type*)Test[1]);
return 0;
}
输出:0 0.5
在这里试试:https://ideone.com/0bN1IP
然而,我发现它的问题是您不能将仅限运行时的枚举值(例如,如果您有 vector<Types>
)放在 <>
当你去使用它时。这严重限制了它的能力。
我的理解是,此限制是由于模板存在仅用于编译时解析。
这里的固有问题是想要动态类型,而 c++ 是静态类型。因此,除非您实现某种大 switch
语句/函数来单独处理每种类型、多态类或其他一些手动类型转换代码,否则不可能在运行时解析这样的动态类型,只有可以在编译时解决的问题。 (如果您可以接受较慢的代码,那么提到的这些其他解决方案可能适合您。)