C ++从属常量

时间:2014-10-28 13:30:57

标签: c++ identifier c++14

我有一组固定的特定于域的类别。每个类别由可枚举类型的相关常量值(本身有用)标识。此外,每个类别都有一组固定的子类别。每个子类别都由相关的常数值(也很有用)标识,在此类别中是唯一的,但在各类别中并不是唯一的。

我试图找到一种方法来为我的子类别声明标识符,'从属'到类别的标识符,即可以通过相关的类别标识符访问子类别标识符,并具有编译时解析。

在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,只留下OneA

1 个答案:

答案 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);
}