我有下面的代码,不仅定义了范围枚举,但也有一个相应的映射,所以我可以直接使用它的枚举器的字符串版本与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和核心语言中引入的功能不同。
做任意号码必须遵循另一个?或者他们可以有不同的时间间隔? –
这可能适用于X宏。 –
看看这个:https://en.wikipedia.org/wiki/X_Macro – peje