C++从属常量

C++ subordinate constants

本文关键字:常量 C++      更新时间:2023-10-16

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

我正试图找到一种方法来声明我的子类别的标识符,即"从属于"类别的标识符的标识符,也就是说,可以通过相关的类别标识符访问子类别标识符,并具有编译时分辨率。

在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

这有点奇怪,但通过定义与类别相对应的对象,您可以为子类别名称启用语法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);
}