假设我有一个enum
:
enum Types
{
TYPE_ASCENDING,
TYPE_DESCENDING
};
我在代码中的任何地方都使用它。说
if(bla < TYPE_ASCENDING)
或说switch/case
。实际的enum
更大。无论检查结果(或其他检查结果)如何,都必须以更漂亮的方式
std::cout
来让用户知道发生了什么。因此,继续if()
示例,可能是这样的:if(bla < TYPE_ASCENDING)
std::cout << "Ascending.\n";
所有这些都发生在一个类中。我的问题:有没有一种方法可以定义某种类型的变量/ STL /任何可以存储类似
enum
和类似std::string
的变量的类型,还可以让我分别使用这两种类型?一个想法是
namespace
,但似乎无法在类中使用它。例如,这是它的样子:namespace Type
{
enum Types
{
ASCENDING,
DESCENDING
};
std::string s[2] {"Ascending", "Descending"};
};
它会被称为
Type::ASCENDING
的if()
和字符串的Type::s[0]
。但是,在类内没有namespace
,所以这不是解决方案。使用
std::map
仅允许我将int
用作索引,因此我只能使用以下内容:std::map<Types, std::string> m {{TYPE_ASCENDING, "Ascending}, {TYPE_DESCENDING, "Descending"}};
作为
m[0]
或m[TYPE_ASCENDING]
,但是我不能称其为在if()
中使用的索引。为此,我必须分别调用enum
,这意味着我同时具有两个变量enum
和map
。我需要一个统一的名称,以避免在整个代码中都使用变量名。如果使用
struct
,则无法直接访问Struct::TYPE_DESENDING
,需要创建一个对象。我可以使用
enum
和std::string
数组/向量,但这意味着我必须分别调用两个变量,并且我希望它们是统一的。我想要什么?
最佳答案
您在本机C ++中实际上没有这种机制。您可以编写一个map / mapper函数。
enum class E
{
ONE,
TWO
};
std::unordered_map<E,std::string> eStrings { {E::ONE,"ONE"},{E::TWO,"two"}};
虽然这是C ++ 11,但是您可以对较旧的C ++版本执行相同的操作
然后你可以像这样使用
std::cout << eStrings[E::ONE];
这里的问题是您必须手动维护它。因此,当您向枚举添加新值时,必须手动向地图添加新条目。
对于编写具有这种行为的类或函数,也是如此。您始终必须复制枚举声明的代码以及对该字符串的映射。
一个解决方案是使用某种工具来生成这些。
您可以在某个文件中定义您的枚举(这只是一些随机格式,仅用于解释这一点。请在您自己的防御文件中选择所需的内容)
E
- ONE
- TWO
然后在头文件和/或cpp文件中生成C ++枚举和Map。
enum class <name>
{
<foreach:> <value>,
};
std::unordered_map< <name> ,std::string> eStrings
{
<foreach:> {<name>::<value>,"<value>"},
};
如果您不喜欢有地图,则此方法非常灵活。如果愿意,还可以生成switch case语句
std::string getString(<name> e)
{
switch(e)
{
<foreach:> case <name>::<value>: return "<value>";
}
}
此处的语法对于任何仅用于可视化该概念的“伪代码”都不是标准。有几种方法可以在那里生成c ++代码。您可以选择任何内容或为此编写自己的程序。
注意:
这也是一个一般概念。您可以将此功能/映射等包装到另一个类中,使其成为静态等以进行优化,而不必将其置于全局范围内。
如果您需要的不仅是映射来查找字符串,还可以使用此概念或另一个进行反向查找的映射来创建类。更多的事实是,您最有可能必须使用外部工具来生成代码。