我有下面的代碼,不僅定義了範圍枚舉,但也有一個相應的映射,所以我可以直接使用它的枚舉器的字符串版本與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