繁体   English   中英

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

[英]How can I get a std::string from an enum type?

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

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()函数吗? 是否有针对此问题的标准解决方案?

一种可能性是地图:

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);

显然这并不是一个很大的差异,但是我发现它至少在某种程度上更具可读性,并且从长远来看,它可能更具可维护性。

没有完美的解决方案,许多库都在做您当前正在做的事情。

但是,如果您希望采用其他方式,则可以将错误转换为类似的类:

#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;
}

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

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

首先是技术性的:C ++没有任何反射机制:已​​编译的符号不再存在(而只是数字)。 而且由于它们不存在,因此您无法将它们找回。

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

解决该问题的一种通用方法是将其分为两部分:一个部分在流级别,另一部分在本地化级别。

当您编写std::cout << 42时会发生什么?

operator<<(ostream&, int)实现实际上调用了use_facet<num_put<char> >(cout.getloc()).do_put(int) ,后者最终使用了定义符号处理方式的numpunct构面,十进制分隔符和数字组分隔符。

处理枚举输出的标准方法是这样的,方法是实现ostrea<<enumeral运算符,该运算符获取构面并对其进行调用,以实际写入该字符串的方法。

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

那不是容易和直接的,但这就是C ++ I / O的构想。

完成所有这些操作后,惯用的获取字符串的方法是使用带有本地化功能的strngstream,该本地化功能支持所有枚举和类所需的方面。

太复杂了? 也许。 但是,如果您认为这太复杂了,那就停止教std::cout << "Hello wrld" << std::endl; 并编写一个更简单的“输出库”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM