是否有可能使用预分配缓冲区的Boost.Format?

我想知道Boost.Format是否支持使用固定宽度/预分配的缓冲区作为输出,而不是由lib本身管理的动态缓冲区?

也就是说,通常你会这样做:

boost::format myfmt("arg1: %1% / arg2: %2%");
// e.g.:
cout << (myfmt % 3.14 % 42);
// or
string s = boost::str( myfmt % "hey!" % "there!");

因此Boost:Format lib将自动处理分配足够的空间并为您管理“输出缓冲区”。

我想知道是否有任何方法使用Boost.Format预定义的非动态缓冲区,也就是说:

const size_t buf_sz = 512;
char big_enough[buf_sz];
boost::format myfmt("arg1: %1% / arg2: %2%");
myfmt.attach_buffer(big_enough, buf_sz);
myfmt % "hey!" % "there!"
// big_enough buffer now contains the result string

我知道我可以对案例,文档和来源进行筛选,但除了缺乏时间之外。 (以及错过某件事情的可能性),知道这件事很有趣:如果不可能,如果有人能够解释为什么(如果有特定的事情) - 这是否是故意的? 它不符合API吗? ...?

免责声明:这个问题不是关于表现!


最初的想法

看起来你可以使用你自己的分配器,然后由boost::format的内部流( internal_streambuf_t )使用它。 这对你的情况足够好吗?

例如,你可以使用类似libstdc ++ array_allocator的东西

不幸的是, boost::format还使用了两个std::vector ,它们不使用自定义分配器,这可能是您的情况中的一个问题?

boost::format如何工作

我研究了boost::format的源码,它是如何工作的(下面描述的是str()<<调用str()或者使用标准std::ostream东西):

  • 格式类分开存储所有参数和格式字符串,有时使用自定义分配器,有时使用默认分配器
  • 当调用str()时,它会创建一个新的std::string并使其足够大以便使用自定义分配器的结果
  • 它将所有参数和静态字符串从格式字符串追加到结果字符串中
  • 最后它通过值返回结果字符串
  • 所以,最终的结果字符串并不存储在format类中,而是在需要时创建。

    因此,即使在使用自定义分配器时可以找到结果字符串的位置,它也只能在调用str()之后/期间使用。 这应该解释为什么它是不可能的:格式化的结果永远不会存储在类的“输出缓冲区”中。

    为什么它像这样工作

    为什么他们这样做我不知道。 我认为这是因为只有在知道所有参数后才能创建结果,这会浪费空间来存储结果,并且对于给定的格式/参数组合,您可能只需要一次结果。 因此,在需要时创建它并不会导致额外的工作,因为通常str()仅调用一次。

    解决方案

  • str()<<创建一些包装,并将结果复制到固定缓冲区中
  • 使用stream_buffer将字符串“流”到缓冲区中(请参阅下面的示例)
  • 继承该类并添加您自己的str()函数,该函数将结果存储在固定的缓冲区中。
  • 使用boost :: iostreams(测试)的可能解决方案:

    #include <iostream>
    #include <boost/format.hpp>
    #include <boost/iostreams/stream.hpp>
    
    int main()
    {
        char buffer[100];
    
        boost::iostreams::stream<boost::iostreams::array_sink>
            stream(buffer, sizeof(buffer));
    
        stream << (boost::format("arg1 = %1%") % 12.5);
        stream << '';  // make sure buffer contains 0-terminated string
    
        std::cout << buffer << std::endl;    
    }
    
    链接地址: http://www.djcxy.com/p/55823.html

    上一篇: Is it possible to use Boost.Format with a preallocated buffer?

    下一篇: Code generation for iOS and android