![](/img/trans.png)
[英]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.