簡體   English   中英

如何消除此枚舉到字符串映射代碼的樣板?

[英]How can I eliminate the boilerplate of this enum to string mapping code?

我有以下代碼,它不僅定義了作用域枚舉,而且還具有與之對應的映射,因此我可以將其枚舉器的字符串化版本直接與 iostream 運算符重載一起使用。

enum class ArbitraryNumbers
{
    One,
    Two,
    Three,
    Four,
    Five
};

namespace
{
    using bm_type = boost::bimap<ArbitraryNumbers, std::string>;
    bm_type const g_arbitraryNumbersMap = boost::assign::list_of<bm_type::relation>
        (ArbitraryNumbers::One, "One")
        (ArbitraryNumbers::Two, "Two")
        (ArbitraryNumbers::Three, "Three")
        (ArbitraryNumbers::Four, "Four")
        (ArbitraryNumbers::Five, "Five")
        ;
}

std::ostream& operator<< (std::ostream& os, ArbitraryNumbers number)
{
    auto it = g_arbitraryNumbersMap.left.find(status);
    if (it != g_arbitraryNumbersMap.left.end())
    {
        os << it->second;
    }
    else
    {
        os.setstate(std::ios_base::failbit);
    }

    return os;
}

std::istream& operator>> (std::istream& is, ArbitraryNumbers& number)
{
    std::string number_string;
    is >> number_string;
    auto it = g_arbitraryNumbersMap.right.find(number_string);
    if (it != g_arbitraryNumbersMap.right.end())
    {
        status = it->second;
    }
    else
    {
        is.setstate(std::ios_base::failbit);
    }

    return is;
}

我想以某種可重復使用的方式包裝它。 我認為最好的解決方案將涉及一些宏,最好是這樣的:

BEGIN_SCOPED_ENUM(ArbitraryNumbers)
    ENUMERATOR(One)
    ENUMERATOR(Two)
    ENUMERATOR(Three)
    ENUMERATOR(Four)
    ENUMERATOR(Five)
END_SCOPED_ENUM()

這非常類似於 MFC,這對我來說主要是立即關閉。 但至少這對眼睛來說要容易得多。 另一點是它消除了樣板文件並且不容易出錯,因為映射不需要與枚舉本身的添加或刪除保持同步。

有沒有辦法用 Boost.Preprocessor、模板技巧或其他一些有用的機制來完成這個任務?

我確實在網上找到了一些想法,但其中大部分是我想避免的手工宏。 我覺得如果我必須采用宏方法,Boost.Preprocessor 將能夠為我做到這一點,但它使用起來非常復雜,我不確定如何使用它來解決這個問題。 此外,我發現的大多數解決方案都已經過時了,我想看看答案是否與 C++03 和 C++14 之間在 STL 和核心語言中引入的功能有所不同。

我只想寫一個數組:

std::string array[] = {"one", "two", "three"};

我想這個問題與自動生成罪表相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM