将格式化的char数组发送到ostream而无需额外的内存复制

时间:2015-02-18 20:58:19

标签: c++ c++11 stdstring iomanip

我需要向ostream发送一个char数组。说我有以下打印功能:

版本1:

void print(ostream &out, const char *str, unsigned len)
{
    out << string(str,len);
}

第2版:

void print(ostream &out, const char *str, unsigned len)
{
    out.write(str,len);
}

以上两个版本都在一定程度上起作用。 版本1看起来效率较低,因为它会创建一个额外的字符串对象(导致内存分配和数据复制)。

但是版本2消除了格式化的可能性。在以下示例中,版本1工作得很好(意味着io操纵器成功将宽度设置为10并将其应用于下一个输出字段):

out << setw(10);
print(out,s,slen);

有没有办法像V1中一样保留功能,但是没有为分配/记忆复制支付额外费用?

2 个答案:

答案 0 :(得分:2)

没有简单或合理的方法可以做到这一点。

根本问题是operator<<(basic_ostream<charT, ...>&, basic_string<charT, ...>)被定义为与operator<<(basic_ostream<charT, ...>&, const charT*)等效的行为,它计算通过basic_ostream<charT, ...>::traits_type::length(str)写入的字符数。使用此界面无法传递长度。

如果你可以重新编写它来取char*而不是const char*,你可以在调用格式化输出操作符之前暂时将其中一个字符设置为NULL,然后重置它它之后的原始价值。

有人建议添加basic_string_view,这会做你想要的,但它并没有包含在C ++ 14中。

答案 1 :(得分:0)

您可以使用boost::iterator_range停止复制,如:

out << boost::iterator_range<const char*>(str, str + len);

我认为您不会影响格式化,因为它基于插入流中的类型。