Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send formatted char array to ostream without extra memory copying

I need to send a char array to ostream. Say I have the following print function:

Version 1:

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

Version 2:

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

Both versions above work to a certain extent. Version 1 looks less efficient because it will create an extra string object (causing memory allocation and data copying).

However Version 2 eliminates formatting possibilities. In the following example Version 1 works great (meaning that io manipulator successfully sets width to 10 and applies it to the next output field) :

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

Is there a way to keep functionality as in V1, but without paying extra for allocation/memcopy?

like image 498
Dmitriy Kumshayev Avatar asked Oct 21 '25 13:10

Dmitriy Kumshayev


1 Answers

There's no easy or reasonable way to do this.

The underlying issue is that operator<<(basic_ostream<charT, ...>&, basic_string<charT, ...>) is defined as behaving equivalent to operator<<(basic_ostream<charT, ...>&, const charT*), which calculates the number of characters to write via basic_ostream<charT, ...>::traits_type::length(str). There's no possibility of passing in a length with this interface.

If you can re-write it to take char* instead of const char*, you can temporarily set one of the characters to NULL before invoking the formatted output operator, and then reset it to it's original value after.

There was a proposal to add basic_string_view, which would do what you're looking for, but it wasn't included in C++14.

like image 119
Collin Dauphinee Avatar answered Oct 23 '25 03:10

Collin Dauphinee