我有一组固定的领域特定类别。每个类别都由可枚举类型的相关常量值(本身有用)标识。此外,每个类别都有一组固定的子类别。每个子类别都由一个相关的常量值(也很有用)来标识,该常量值在该类别中是唯一的,但在所有类别中不是唯一的。
我正在尝试找到一种方法来声明我的子类别的标识符,“从属于”类别的标识符,即子类别标识符可以通过相关的类别标识符访问,具有编译时分辨率。
在 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
?
最佳答案
这有点奇怪,但是通过定义与类别相对应的对象,您可以为子类别名称启用语法 One.A
(Live at Coliru):
#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);
}
关于C++ 从属常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26609650/