创建结构作为枚举类成员

Creating a struct as enum class member

本文关键字:成员 枚举 结构 创建      更新时间:2023-10-16

我正在努力为库创建一个多级枚举。

  • 我想要这样的东西(不一定完全是(:
Book::Category::PROGRAMMING::C_PLUS_PLUS

其中BookstructCategory(目前(是enum class
基本上,我想嵌套枚举

我知道我可以做:

Book::Category::PROGRAMMING_C_PLUS_PLUS

但是这不仅会在Category中创建一长串值,而且会使维护它成为一场噩梦(我尝试用 30 这样做,这已经是一个令人头疼的问题(。

我想分而治之,克服这个问题。

编辑1:我不希望它成为std::string的原因是它的价值可以是任何东西。我想限制Category的领域.

不,PROGRAMMING不是我图书馆的主要部分。让我尝试使用类和继承。

基本上,我想要enum的原因是有一组固定的有效常量。


引用:

  • 枚举类可以嵌套吗? ->我需要创建Book的对象,因此它不能是命名空间。我无法理解使用模板的答案。
  • 为什么枚举类比普通枚举更受欢迎? -> 没有回答我的问题。

您不能嵌套enums,但是,您可以执行以下操作:

struct Book {
struct Category {
enum class PROGRAMMING {
// ...
};
enum class COOKING {
// ...
}; 
};
};

类似于在链接问题中使用命名空间,但由于它位于类内部并且您无法这样做,因此您可以只使用另一个结构。

你可以这样做,但这将是一个糟糕的设计

一种常见的代码气味是使用enum来表示显然应该是一个类 - 这里的情况是您希望C_PLUS_PLUS类型是PROGRAMMING类别的派生。

但是,enum最好用于描述可能的状态,并且无法通过设计进行继承,如您在其中一个参考中指出的那样。在我看来,你最好的做法是在Category中制作两个单独的成员变量,它们可以保存PROGRAMMINGC_PLUS_PLUS,并取消它们作为enums 的状态。

思考:什么最能概括一个开放式领域,如书籍类型/子类型?您是否打算用enum每种可能性进行编程?或者只使用两个string(例如genresubgenre(更适合这样的开放式字段?

或者,也许,如果你专门使用PROGRAMMING书籍作为你设计的主要部分,PROGRAMMING变成一个类,C_PLUS_PLUS成为类中enum的一部分。但是不要让它们都enums- 这只是在路上提出问题,并不能解决您已经描述的维护问题。

编辑:从我发表的评论中添加 -

通过强迫它们固定和恒定,无论如何你都会强迫自己陷入"头痛"的境地。你强迫自己维护一个恒定的有效枚举列表,这些枚举可能会在某个时候发生变化,此时你必须更新枚举列表并重新编译代码。这里的一个可塑性解决方案是允许它们是字符串,并在启动或其他东西时读取.txt文件,并将其作为可接受的值列表,如果需要验证,您可以检查这些值。

应应回答者的要求,我发布我的实现以供将来参考。
这是Book

struct Book
{
// A Map of categories and its list of sub-categories
static std::map< std::string, std::vector< std::string > > Categories;
// default parameter for unit testing, 
// thanks to https://stackoverflow.com/questions/40297782/c-unit-testing-check-output-is-correct/59374648#59374648
static void initBookCategories(std::string file_name = "categories.txt")
{
// Open the file in read mode
std::ifstream allowed_categories(file_name);
// Check if file open is unsuccessful
if(!allowed_categories)
{
// Signal error and exit
std::cerr << "nnFile Not Found!nError Initialising DB! Exiting...";
return;
}
// Read the category_name
std::string category_name;
// Until there are categories left
while(std::getline(allowed_categories, category_name))
{
// Read the whole sub-category list
std::string subcategory_names;
// Untill end of line
std::getline(allowed_categories, subcategory_names);
// Convert to std::stringstream for parsing
std::istringstream parse_subcategories(subcategory_names);
// Skip the empty line
allowed_categories.ignore();
// Now read the sub-categories
// Need a std::vector to store the list of subcategory names
std::vector< std::string > subcategory_list;
// Reusing subcategory_names for each subcategory_name
while(parse_subcategories >> subcategory_names)
{
// Add to the list of sub-categories
subcategory_list.push_back(subcategory_names);
}
// Add this newly read category with its list of subcategories our map
Categories.insert(std::pair< std::string, std::vector< std::string > >(category_name, subcategory_list));
}
}
static void getCategoryList()
{
// For each category
for(std::pair< const std::string, std::vector< std::string > >& category : Categories)
{
// List the sub-categories
int index = 0;
// Print the category name
std::cout << " " << category.first << ":n";
// Loop over the sub-categories
for(std::string& subcategory_name : category.second)
{
// Printing each sub-category in a line
std::cout << "   " << ++index << ") " << subcategory_name << "n";
}
}
}
};
std::map< std::string, std::vector< std::string > > Book::Categories;

我们的主要函数使用它:

int main()
{
Book::initBookCategories();
Book::getCategoryList();
return 0;
}

最后但并非最不重要的一点是,categories.txt格式:

PROGRAMMING
C_PLUS_PLUS C PYTHON JAVA SQL
MATHEMATICS
CALCULUS ALGEBRA DISCRETE
BIOLOGY
ZOOLOGY BOTANY MICROBIOLOGY BIOTECHNOLOGY
CHEMISTRY
ORGANIC INORGANIC PHYSICAL
SOCIAL_STUDIES
POLITICAL_SCIENCE GEOGRAPHY HISTORY CIVIL_SCIENCE
BUSINESS_ADMINISTRATION
ACCOUNTS MANAGEMENT STATISTICS ECONOMICS
SCIENCE_FICTION
SPACE ALIENS FUTURE WAR ADVENTURE
LITERATURE
ENGLISH HINDI COMEDY NOVEL
PHYSICS
MECHANICS FLUIDS NUCLEAR THERMODYNAMICS
ARTS_AND_HUMANITIES
PHILOSOPHY SOCIOLOGY PSYCHOLOGY ANTHROPOLOGY

谢谢!