用于枚举序列化的函数模板

发布于 2024-11-02 08:08:15 字数 601 浏览 2 评论 0原文

我已经编写了一个函数模板,用于将枚举序列化到我们的流类或从我们的流类序列化枚举(是的,我知道 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;
}

这些是简单的模板,它们在我的用于(反)序列化枚举项向量的函数模板中也能很好地工作。但我担心它们过于通用,即它们也适用于不是 enums 但可以转换为 int 或从 int 转换的类型 T。我可以改进枚举序列化模板(或者向量序列化模板)以确保它们仅适用于枚举向量吗?

I have written a function template for serialization of enums to/from our stream class (Yes, I know boost::serialization, but it is not an option in my situation). Enums by convention in our company are serialized as 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;
}

These are simple templates, and they work nicely also in my function templates for (de)serializing a vector of enumeration items. I'm worried though that they are overly generic, i.e. that they get applied also for types T that are not enums but can be cast to/from an int. Can I improve the enum-serialization templates (or maybe the vector-serialization templates) to make sure they only apply to vectors of enums?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谈情不如逗狗 2024-11-09 08:08:15

这里需要进行两项改进:并不总是序列化为 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_ifis_enum。但是,我认为您需要underlying_type你自己。 (当然,在最坏的情况下,您可以自己完成这三个操作,但如果我没记错的话,is_enum 可能会很痛苦。)

There are two improvements to be made here: not always serializing as int (not all enums are), but as whatever the underlying type is. And, as your request, to only accept enums.

The latter is easily solved with std::enable_if and std::is_enum:

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

// and likewise for operator>>

And for the former, do the following inside the function:

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>>

This requires C++0x.

If that's not an option, both enable_if and is_enum can be found within Boost. However, I think you'll need to make underlying_type yourself. (And of course, in the worse case you can do all three yourself, though is_enum can be a pain, if I recall correctly.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文