Boost logo

Boost :

Subject: Re: [boost] Variadic append for std::string
From: Christof Donat (cd_at_[hidden])
Date: 2017-01-23 05:23:23


Hi,

Am 23.01.2017 09:55, schrieb Hans Dembinski:
> On 20 Jan 2017, at 20:03, Christof Donat <cd_at_[hidden]> wrote:
>> auto my_new_str = concat("Hello", ", ", "World", "!").str();
>>
>> [...]
>
> Your last proposal was without the ".str()", which made more sense:
>
> auto my_new_str = concat("Hello", ", ", "World", "!");
>
> I hope this was just a typo.

Actually no, it wasn't. The idea is, that functions like concat(),
join() and format() return string factories, instead of strings. This is
an advantage, when you combine calls to these functions:

auto my_new_str =
     concat("Hello ",
            join(", ",std::begin(my_nums), std::end(my_nums)),
            format(" the file %1% contains %2% bytes", filename,
filesize)).str();

As you see, I only call str() on the return value of concat(). We can
make the string factories write to a preallocated buffer. Here the
concat facory will allocate enough memory, and ask the join string
factory, and the format string factory to write directly to that buffer.
If join() and format() would return strings, we'd have to copy them in
concat().

An alternative to a function like str() could be an implicit conversion
operator to std::string. Then we would write:

auto my_new_str = std::string{concat("Hello ",
                                      join(", ",std::begin(my_nums),
std::end(my_nums)),
                                      format(" the file %1% contains %2%
bytes", filename, filesize))};

or

std::string my_new_str{concat("Hello ",
                               join(", ",std::begin(my_nums),
std::end(my_nums)),
                               format(" the file %1% contains %2% bytes",
filename, filesize))};

Again we pass two string factories to concat(). Therefore it can
allocate enough memory and ask these factories to write there. The only
difference is, that all that does not happen in a call to str(), but in
a call to operator std::string (). I am not completely opposed to
implicit conversions, but in this case, an explicit function call feels
better to me. Sorry, that I don't have a better reason at the moment.

No matter if we use str() of an implicit conversion, combining these
calls also lets us use tag parameters for formatting details:

format("%1% is %2% and %3%", 42,
                              concat(format::hex<int>, 42, " in hex"),
                              concat(format::oct<int>, 42, " in
oct")).str();

Other than the iostream manipulators these formatting instructions have
a defined scope. And still we don't have to copy temporary strings,
because we pass string factories.

Christof


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk