如何从枚举类型中获取std :: string?

时间:2013-10-17 03:51:26

标签: c++ c++11 enums

我有一些错误代码,我想表示为字符串:

enum class ErrorCode
{
    OK,
    InvalidInput,
    BadAlloc,
    Other
};

我想创建一种直观而简单的方法来获取代表这些错误的字符串。简单的解决方案是:

std::string const ErrorCode2Str(ErrorCode errorCode)
{
  switch (errorCode)
  {
    case OK:
    return "OK";
    case InvalidInput:
    return "Invalid Input";
    case BadAlloc:
    return "Allocation Error";
    case Other:
    return "Other Error";
    default:
    throw Something;
  }
}

有更好的方法吗?我可以以某种方式将ErrorCode重载为字符串转换吗?我可以创建ErrorCode::str()功能吗?这个问题有标准解决方案吗?

3 个答案:

答案 0 :(得分:6)

一种可能性是地图:

class to_str { 
    std::unordered_map<ErrorCode, std::string> strings;
public:
    to_str() {
        strings[ErrorCode::OK] = "Ok";
        strings[ErrorCode::InvalidInput] = "Invalid Input";
        strings[ErrorCode::BadAlloc] = "Allocation Error";
        strings[ErrorCode::Other] = "Other";
    }

    std::string operator()(ErrorCode e) { 
        return strings[e];
    }
};

// ...
auto e = foo(some_input);
if (e != ErrorCode::OK)
   std::cerr << to_str()(e);

这显然不是巨大的差异,但我发现它至少略微更具可读性,并认为从长远来看它可能更容易维护。

答案 1 :(得分:3)

没有完美的解决方案,很多图书馆都在做你目前正在做的事情。

但是如果你想要一种不同的方式,你可以把错误变成这样的类:

#include <iostream>
#include <string>
class Error
{
public:
    Error(int key, std::string message) : key(key), message(message){}
    int key;
    std::string message;
    operator int(){return key;}
    operator std::string(){ return message; }
    bool operator==(Error rValue){return this->key == rValue.key; } 
};

int main()
{
    Error e(0, "OK");

    int errorCode = e;
    std::string errorMessage = e;

    std::cout << errorCode << " " << errorMessage;
}

答案 2 :(得分:1)

虽然存在许多简单的方法来执行枚举到字符串或字符串到枚举的转换,但我想在这里考虑一种更通用的方法。

为什么C ++不允许本机构造呢?主要有两个原因:

第一个是技术性的:C ++没有任何反射机制:编译符号简单不再存在(并且只是数字)。而且由于它们不存在,你无法取回它们。

第二个是编程问题:编译器和程序员之间“共享”枚举。字符串文字在progam和最终用户之间共享。那可能不是程序员,可能不会说英语(而且我们不知道他说的是什么)。

解决问题的一般方法是将其分为两部分:一部分是流级别,另一部分是本地化级别。

std::cout << 42时会发生什么?

operator<<(ostream&, int)实现实际上会调用use_facet<num_put<char> >(cout.getloc()).do_put(int),而numpunct最终会使用ostrea<<enumeral方面来定义如何处理符号,小数点分隔符和数字组分隔符。

处理枚举输出的标准方法是这样,通过实现一个std::cout << "Hello wrld" << std::endl;运算符来获取一个方面,并在其上调用一个实际写入该字符串的方法。

这样的方面可以实现多次,并且可用于每种支持的语言。

这不容易和直截了当,但这就是C ++ I / O的构思方式。

一旦你完成了所有这些,获得字符串的惯用方法是使用一个充满本地的strngstream,它支持所有enums和类所需的facet。

太复杂了?也许。但如果您认为这太复杂,请停止教{{1}}并编写更简单的“输出库”。