3

我需要向 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 中的功能,但无需为分配/内存复制支付额外费用?

4

2 回答 2

2

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

根本问题是,operator<<(basic_ostream<charT, ...>&, basic_string<charT, ...>)它的行为等同于operator<<(basic_ostream<charT, ...>&, const charT*),它计算要通过 写入的字符数basic_ostream<charT, ...>::traits_type::length(str)。使用此接口不可能传递长度。

如果您可以将其重写为 takechar*而不是const char*,您可以在调用格式化输出运算符之前将其中一个字符临时设置为NULL,然后在之后将其重置为原始值。

有一个要添加的建议basic_string_view,它可以满足您的需求,但它并未包含在 C++14 中。

于 2015-02-18T21:41:39.803 回答
0

您可以使用boost::iterator_range来停止复制,如下所示:

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

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

于 2015-02-18T21:44:27.800 回答