簡體   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