我有一组固定的特定于域的类别。每个类别由可枚举类型的相关常量值(本身有用)标识。此外,每个类别都有一组固定的子类别。每个子类别都由相关的常数值(也很有用)标识,在此类别中是唯一的,但在各类别中并不是唯一的。
我试图找到一种方法来为我的子类别声明标识符,'从属'到类别的标识符,即可以通过相关的类别标识符访问子类别标识符,并具有编译时解析。
在C ++ 14中执行此操作的适当方法是什么?
标识符只是可枚举类型的常量值(让它基于int)。
以下是我的尝试:
enum Category
{
One = 1,
Two = 2,
Three = 3
};
template<Category categoryName> struct Subcategory;
template<> struct Subcategory<Category::One>
{
enum
{
A = 0,
B = 1
};
};
我们可以通过Subcategory<Category::One>::A
访问子类别标识符(不是激动人心的......)
表达式看起来太长了,我试图找到一个解决方案,为访问A提供更简洁的表达式。沿着这条路径的最后一步是使第一个枚举未命名...
实际上,正如pepper_chico所说,表达式被缩减为Subcategory<One>::A
。
是否有一个解决方案(可能不是基于模板的)可以删除标识符Subcategory
,只留下One
和A
?
答案 0 :(得分:1)
这有点奇怪,但通过定义与类别对应的对象,您可以为子类别名称(Live at Coliru)启用语法One.A
:
#include <iostream>
#include <type_traits>
enum class Category
{
One = 1,
Two = 2,
Three = 3
};
template <Category> struct CategoryDescriptor;
#define DECLARE(name,...) \
template <> \
struct CategoryDescriptor<Category::name> { \
enum sub_type { __VA_ARGS__ }; \
constexpr operator Category() const { return Category::name; } \
}; \
constexpr CategoryDescriptor<Category::name> name{}
DECLARE(One, A, B);
DECLARE(Two, C, D);
DECLARE(Three, A, C, E);
#undef DECLARE
std::ostream& operator << (std::ostream& os, Category c) {
return os << static_cast<std::underlying_type<Category>::type>(c);
}
template <Category C>
using SubCategoryOf = typename CategoryDescriptor<C>::sub_type;
int main() {
std::cout << "One = " << One << "\n"
"One.A = " << One.A << "\n"
"Two = " << Two << "\n"
"Two.D = " << Two.D << "\n"
"Three = " << Three << "\n"
"Three.A = " << Three.A << '\n';
// Category names convert to Category
auto foo = [](Category){};
foo(Three);
// Subcategory names convert to SubCategoryOf<Category>
auto bar = [](SubCategoryOf<Two>){};
bar(Two.C);
}