代码之家  ›  专栏  ›  技术社区  ›  Kylotan

将类型序列与iostream混合的最简单方法?

  •  0
  • Kylotan  · 技术社区  · 15 年前

    我有一个功能 void write<typename T>(const T&) T read<typename T>() 从istream读取T。我基本上是将iostream用作纯文本序列化格式,这显然对大多数内置类型都适用,尽管我还不确定如何有效地处理std::strings。

    void write<typename T>(const std::vector<T>&) 或者基于迭代器的等价物(尽管在实践中,它总是与向量一起使用)。然而,虽然编写一个遍历元素并写出它们的重载非常容易,但是这并没有添加足够的信息来允许匹配的read操作知道每个元素是如何被分隔的,这本质上与我在单个std::string中遇到的问题相同。

    有没有一种方法可以适用于所有基本类型和std::string?或者我可以使用两个重载,一个用于数值类型,一个用于字符串?(可以使用不同的分隔符,也可以使用分隔符转义机制的字符串。)

    当遇到这样的问题时,我很欣赏这样一种明智的倾向,那就是说,“你不想那样做”,并提出更好的方法,但我真的希望有与我所问问题直接相关的建议,而不是你认为我应该问的问题。:)

    4 回复  |  直到 15 年前
        1
  •  1
  •   anon anon    15 年前

    一个通用的序列化框架是 坚硬的

        2
  •  0
  •   Community CDub    7 年前

    基本上,你必须创建一个文件格式。当您被限制为内置、字符串和它们的序列时,您可以使用空格作为分隔符,将字符串包装在 " (逃避任何 -然后呢 \ ,并选择任何不用于流式处理的内置类型作为序列分隔符。存储序列的大小可能也有帮助。

    例如,

    5 1.4 "a string containing \" and \\" { 3 "blah" "blubb" "frgl" } { 2 42 21 }

    可能是 int ( 5 ),一个 float ( 1.4 ),一个字符串( "a string containing " and \" "blah" "blubb" ,和 "frgl" ),以及2的序列 内景 42 21 ).

    或者你可以按照尼尔的建议去做 in his comment

    { 27 'a' ' ' 's' 't' 'r' 'i' 'n' 'g' ' ' 'c' 'o' 'n' 't' 'a' 'i' 'n' 'i' 'n' 'g' ' ' '"' ' ' 'a' 'n' 'd' ' ' '\' }

        3
  •  0
  •   Steve Jessop    15 年前

    对于一个非常简单的等价物,可以输出 uint32_t 作为“ui4”后跟4个字节的数据,a int8_t a<len>ui1 或者一些缩写,比如 s<len>: . 读者确实很简单。

    这有明显的缺点:类型的大小和表示形式必须独立于平台,并且输出既不是人类可读的,也不是特别压缩的。

    你可以使它大部分人可读,尽管使用ASCII而不是算术类型的二进制表示(注意数组:在输出任何数组之前,可能需要计算整个数组的长度,或者可以使用分隔符和终止符,因为不需要字符转义),通过选择性地添加一个大的人眼可见分隔符,反序列化程序会忽略它。例如, s16:hello, worlds12:||s12:hello, world s16:hello, worlds12:s12:hello, world . 阅读时要小心,看起来像分隔符的序列实际上可能不是一个,你必须避免陷入假设这样的陷阱 s5:hello|| s15:hello||s5:hello|| .

    除非对代码大小有非常严格的限制,否则使用现成的通用序列化程序可能比编写专门的序列化程序更容易。使用SAX读取简单的XML并不困难。这就是说,每个人和他的狗都写了“最后,序列化程序/解析器/任何可以节省我们手工编写序列化程序/解析器/任何东西”的文章,取得了或多或少的成功。

        4
  •  0
  •   Artem Sokolov    15 年前

    你可以考虑使用 boost::spirit