[英]Why does std::is_literal_type<std::String> == false and how can I get around it?
[英]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.