如何将此枚举的样板消除为字符串映射代码?

时间:2015-09-25 22:02:51

标签: c++ boost enums iostream c++14

我有以下代码,不仅定义了一个范围的枚举,而且还有一个相应的映射,所以我可以直接使用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将能够为我做这个,但它使用非常复杂,我不知道如何使用它来解决这个问题。我发现的大多数解决方案都是过时的,我想看看答案是否与STL和C ++中引入的功能有所不同。

1 个答案:

答案 0 :(得分:-2)

我只是写一个数组:

select a.department, a.AA, a.BB, b.CC, b.DD
  from ( select department, AA, BB
           from outlier_report
          group by department, concat(resourcename, entitlementname)
       ) a
  join ( select department, CC, DD
           from outlier_report
          group by department
       ) b on a.department = b.department

我猜这个问题与自动生成sin表一样。