假设我有一个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::ASCENDINGif()和字符串的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,这意味着我同时具有两个变量enummap。我需要一个统一的名称,以避免在整个代码中都使用变量名。

如果使用struct,则无法直接访问Struct::TYPE_DESENDING,需要创建一个对象。

我可以使用enumstd::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 ++代码。您可以选择任何内容或为此编写自己的程序。

注意:

这也是一个一般概念。您可以将此功能/映射等包装到另一个类中,使其成为静态等以进行优化,而不必将其置于全局范围内。



如果您需要的不仅是映射来查找字符串,还可以使用此概念或另一个进行反向查找的映射来创建类。更多的事实是,您最有可能必须使用外部工具来生成代码。

10-07 19:12
查看更多