c++ - 如何使用 Cereal 序列化枚举类型?

标签 c++ serialization enums cereal

例如

enum Color {RED, BLUE, YELLOW};

而且我想用麦片连载类型

Color c = RED;
JSONOutputArchive archive(std::cout);
archive(c);

输出看起来像

"value0" : "RED"

"value0" : RED

最佳答案

您想要的输出是任何序列化库都无法自动执行的,因为您为枚举值提供的名称只有编译器知道。

通常在这种情况下,您需要提供可以在字符串表示和枚举数值之间进行转换的代码(例如 Enum to String C++ ),或者使用 library它会自动为您执行此操作。

假设您拥有此功能。然后,您需要编写一对专门用于您的枚举的最小序列化函数。

这是一个完整的示例。你如何选择从枚举到字符串取决于你,我选择了两个 map ,因为它不需要我真正的努力,但你可以轻松地将所有这些隐藏在一个宏后面,这个宏会为你生成所有需要的代码:

#include <cereal/archives/json.hpp>
#include <iostream>
#include <sstream>
#include <map>

enum Color {RED, BLUE, GREEN};
enum AnotherEnum {HELLO_WORLD};

std::map<Color, std::string> ColorMapForward = {{RED, "RED"}, {BLUE, "BLUE"}, {GREEN, "GREEN"}};
std::map<std::string, Color> ColorMapReverse = {{"RED", RED}, {"BLUE", BLUE}, {"GREEN", GREEN}};

std::string Color_tostring( Color c )
{
  return ColorMapForward[c];
}

Color Color_fromstring( std::string const & s )
{
  return ColorMapReverse[s];
}

namespace cereal
{
  template <class Archive> inline
  std::string save_minimal( Archive const &, Color const & t )
  {
    return Color_tostring( t );
  }

  template <class Archive> inline
  void load_minimal( Archive const &, Color & t, std::string const & value )
  {
    t = Color_fromstring( value );
  }
}

int main()
{
  std::stringstream ss;

  {
    cereal::JSONOutputArchive ar(ss);
    ar( RED );
    ar( BLUE );
    ar( GREEN );
    ar( HELLO_WORLD ); // uses standard cereal implementation
  }

  std::cout << ss.str() << std::endl;
  std::stringstream ss2;

  {
    cereal::JSONInputArchive ar(ss);
    cereal::JSONOutputArchive ar2(ss2);

    Color r, b, g;
    AnotherEnum a;

    ar( r, b, g, a );
    ar2( r, b, g, a );
  }

  std::cout << ss2.str() << std::endl;
}

给出输出:

{
    "value0": "RED",
    "value1": "BLUE",
    "value2": "GREEN",
    "value3": 0
}
{
    "value0": "RED",
    "value1": "BLUE",
    "value2": "GREEN",
    "value3": 0
}

关于c++ - 如何使用 Cereal 序列化枚举类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39969621/

相关文章:

c++ - 为 C 和 C++ 安装 MessagePack 实现时出现链接器错误

c++ - 在 C++ 中的 "using namespace::X"中的前导::是什么意思

c# - RestSharp 序列化/反序列化命名转换

android - 尝试将序列化对象从 Android App 传输到 Servlet 时收到 NoSuchMethodException

java - Enum.valueOf 对扩展 Enum 的类的未知类型发出警告?

c# - 来自字符串、整数等的枚举

c++ - 初始化模板类成员的问题

c++ - 当问题本质上完全不同时,为什么选择 C2259?

c++ - 在 C++ 中对某些序列化进行原型(prototype)化的快捷方式?

java - 映射值应该声明为常量还是枚举?