将字符绑定到枚举类型

10

我有一段代码与这个非常相似:

class someclass
{
public:
enum Section{START,MID,END};
vector<Section> Full;
void ex(){
    for(int i=0;i<Full.size();i++)
    {
        switch (Full[i])
        {
        case START :
                  cout<<"S";
                  break;
        case MID :
                  cout<<"M";
                  break;
        case END:
            cout<<"E";
            break;
        }
    }
    }
};

现在想象一下,我有很多枚举类型,它们的名称更长......那么我得到的代码不是很好看,我在想是否可能将特定字符绑定到一个枚举类型,并且可以做类似这样的事情:

for(int i=0;i<Full.size();i++)
    {
        cout<(Full[i]).MyChar();
    }

还有其他方法可以使这段代码“更漂亮”吗?

这可行吗?

你可以始终使用std::map<Section, char>,但我不确定在这么少的值集合下,代码会变得更加清晰。至少你可以将转换封装在一个函数中,以便重复使用。 - cdhowie
2
这里使用std::map似乎有些大材小用,一个简单的数组就足够了:cout << "SME"[Full[i]]。(但仍需要改进以提高可管理性和安全性。) - user743382
可能需要一个 #define 头文件。#define START 'S' ... - Seth Hays
3个回答

21

不幸的是,您无法做太多事情来清理它。如果您可以访问C++11的强类型枚举器功能,则可以执行以下操作:

enum class Section : char {
     START = 'S',
     MID = 'M',
     END = 'E',
};

然后你可以做这样的事情:

std::cout << static_cast<char>(Full[i]) << std::endl;

如果您无法访问此功能,则没有太多可以做的,我的建议是拥有一个全局映射 std::map<Section, char>,它将每个 enum 部分与字符相关联,或者具有原型的助手函数:

inline char SectionToChar( Section section );

这只是以更易访问的方式实现了switch()语句,例如:

inline char SectionToChar( Section section ) {
     switch( section )
     {
     default:
         {
             throw std::invalid_argument( "Invalid Section value" );
             break;
         }
     case START:
         {
             return 'S';
             break;
         }
     case MID:
         {
             return 'M';
             break;
         }
     case END:
         {
             return 'E';
             break;
         }
     }
}

第一个解决方案看起来很不错,但不幸的是我无法访问它。 - Ravid Goldenberg
我认为你需要 case Section::START: 等等吗? - aschepler
1
@aschepler 不需要为非强类型全局 enum 限定作用域。 - Thomas Russell

6
在这种情况下,您可以使用技巧来转换字符。
enum Section{
    START = (int)'S',
    MID   = (int)'M',
    END   = (int)'E'
};

...

inline char getChar(Section section)
{
    return (char)section;
}

好像它可以工作,但它是否“合法”呢? 我的意思是,它是否被认为是良好的编程? - Ravid Goldenberg
3
它是合法的,是的。它是好的编程吗?嗯,如果不知道你想要实现什么,我无法回答。但它确实更漂亮。 - Seth Hays

0

我认为在这种情况下最好的解决方案是使用地图:

#include <iostream>
#include <map>
class someclass
{
    public:
    enum Section{START = 0,MID,END};
    map<Section,string> Full;

    // set using Full[START] = "S", etc

    void ex(){
        for(int i=0;i<Full.size();i++)
        {
            cout << Full[i];
        }
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接