我想知道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吗? ...?
免责声明:此问题不关于效果!
答案 0 :(得分:5)
查看source,您似乎可以使用自己的分配器,然后由internal_streambuf_t
的内部流(boost::format
)使用。这对你的情况是否足够好?
例如,您可以使用类似libstdc ++ array_allocator
的内容不幸的是,boost::format
还使用了一些不使用自定义分配器的std::vector
,这可能是您的问题?
boost::format
如何运作我查看了boost::format
的来源,这就是它的工作原理(下面介绍的是str()
,<<
调用str()
或使用标准std::ostream
东西):
str()
时会创建一个新的std::string
,并使用自定义分配器使其足够大以获得结果因此,最终结果字符串不会存储在格式类中,而是在需要时创建。
因此,即使您在使用自定义分配器时可以找到结果字符串的位置,也只能在调用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 << '\0'; // make sure buffer contains 0-terminated string
std::cout << buffer << std::endl;
}