шаблон функции для сериализации перечислений

Я написал шаблон функции для сериализации перечислений в / из нашего класса потока (да, я знаю boost :: serialization, но в моей ситуации это не вариант). В нашей компании перечисления по соглашению сериализуются как int:

template<typename T>
Stream& operator<<( Stream& s, T const& value )
{
    s << ( int ) value;
}

template<typename T>
Stream& operator>>( Stream& s, T & value )
{
    int v;
    s >> v;
    value = (T) v;
}

Это простые шаблоны, и они также хорошо работают в моих шаблонах функций для (де) сериализации вектора элементов перечисления. Однако меня беспокоит то, что они слишком общие, т.е. что они применяются также к типам T, которые не являются enums, но могут быть преобразованы в / из int. Могу ли я улучшить шаблоны enum-сериализации (или, может быть, шаблоны векторной сериализации), чтобы убедиться, что они применяются только к векторам enums?


person andreas buykx    schedule 19.04.2011    source источник


Ответы (1)


Здесь нужно сделать два улучшения: не всегда сериализовать как int (не все перечисления), а как какой бы ни был базовый тип. И, как ваша просьба, принимать только перечисления.

Последнее легко решается с помощью std::enable_if и std::is_enum:

typename std::enable_if<std::is_enum<T>::value, Stream&>::type
    operator<<( Stream& s, T const& value )

// and likewise for operator>>

В первом случае внутри функции выполните следующие действия:

Stream& operator<<( Stream& s, T const& value )
{
    typedef typename std::underlying_type<T>::type safe_type;
    s << static_cast<safe_type>(value);
}

// and likewise for operator>>

Для этого требуется C ++ 0x.

Если это не вариант, в Boost можно найти и enable_if, и is_enum. Однако я думаю, вам необходимо сделать underlying_type себя. (И, конечно, в худшем случае вы можете сделать все три самостоятельно, хотя is_enum может быть проблемой, если я правильно помню.)

person GManNickG    schedule 19.04.2011