Мы собираемся перенести (в течение следующих двух лет) все наши компиляторы в компиляторы С++ 11-ready.
Наши клиенты будут использовать наши заголовки, и теперь мы можем писать (более или менее с нуля) заголовки для нашего нового API.
Итак, мы должны выбирать между сохранением списков С++ 03 (со всеми их бородавками) или использовать класс упаковки для имитации нотации С++ 11, потому что мы хотим, в конце концов, переместить эти перечисления на С++ 11.
Идиома "LikeEnum", предложенная ниже жизнеспособного решения, или неожиданные сюрпризы скрываются за ней?
template<typename def, typename inner = typename def::type>
class like_enum : public def
{
typedef inner type;
inner val;
public:
like_enum() {}
like_enum(type v) : val(v) {}
operator type () const { return val; }
friend bool operator == (const like_enum & lhs, const like_enum & rhs) { return lhs.val == rhs.val; }
friend bool operator != (const like_enum & lhs, const like_enum & rhs) { return lhs.val != rhs.val; }
friend bool operator < (const like_enum & lhs, const like_enum & rhs) { return lhs.val < rhs.val; }
friend bool operator <= (const like_enum & lhs, const like_enum & rhs) { return lhs.val <= rhs.val; }
friend bool operator > (const like_enum & lhs, const like_enum & rhs) { return lhs.val > rhs.val; }
friend bool operator >= (const like_enum & lhs, const like_enum & rhs) { return lhs.val >= rhs.val; }
};
Что позволит нам обновить наши перечисления без необходимости внесения нежелательных изменений в код пользователя:
// our code (C++03) | our code C++11
// --------------------------------------+---------------------------
|
struct KlingonType | enum class Klingon
{ | {
enum type | Qapla,
{ | Ghobe,
Qapla, | Highos
Ghobe, | } ;
Highos |
} ; |
} ; |
|
typedef like_enum<KlingonType> Klingon ; |
|
// --------------------------------------+---------------------------
// client code (both C++03 and C++11)
void foo(Klingon e)
{
switch(e)
{
case Klingon::Qapla : /* etc. */ ; break ;
default : /* etc. */ ; break ;
}
}
Примечание. Функция LikeEnum была вдохновлена типом безопасного итеративного перехвата
Примечание 2: Совместимость источника не распространяется на ошибку компиляции из-за неявного преобразования в int: они считаются нежелательными, и клиент будет уведомлен заранее, чтобы сделать явное преобразование целых чисел.