繁体   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