Boost logo

Boost :

Subject: Re: [boost] Variadic append for std::string
From: Olaf van der Spek (ml_at_[hidden])
Date: 2017-01-12 14:05:38

On Wed, Jan 11, 2017 at 5:45 PM, Christof Donat <cd_at_[hidden]> wrote:

> Hi,
> Am 11.01.2017 16:03, schrieb Olaf van der Spek:
>> On Wed, Jan 11, 2017 at 10:02 AM, Christof Donat <cd_at_[hidden]> wrote:
>>> The significantly better alternative is std::ostringstream. I think our
>>> debate showed very nicely, that all the options, we have come up with to
>>> simplify the concatenation of strings are significantly inferior in
>>> total,
>>> though we could find examples, where they slightly improve readability.
>> Interface is important, as is performance.. and performence of
>> ostringstream sucks..
> Well, but obviously up to now we didn't manage to come up with a solution,
> that has a similar simple, maybe even better interface and allows for
> faster implementations.
> I'll try again:
> Basically the Idea of that kind of interface should work as well for a
> high performance solution. Let's start with this syntax:
> auto myString = (cat() + "Hello"s + " "s + "World! "s + 42).str();

I like fmt's syntax much more:

string s = fmt::format("The answer is {}", 42);

I really don't get why we should bother with the (cat(...)).str() bit.

> "cat" would return an object that collects all the values by reference,
> and concatenates them in one go in the call to str(). Then when str() runs,
> the information about the string length can be calculated, or at least
> estimated correctly and no data needs to be copied unnecessarily. I am
> sure, you see the structural similarity to the usage of std::ostringstream
> as well. I just chose to use the operator +, because
> 1. we don't have stream manipulators here, so we don't want people to
> think, that we are talking about streams and
> 2. strings already can be concatenated with operator +. Therefore this is
> an intuitive and not very surprising interface for string concatenation.
> People might just think, they can add numbers to strings as well without a
> "cat"-object. There is some room for confusion, but it is much less, than
> people thinking, strings are a kind of streams. Maybe "cat" is not the best
> name for this function template, it should express, that here the
> concatenation includes conversions.
> We also need an extensible way to define these conversions, because we
> also will want to add e.g. complex<myBigRelativeType, myBigRelativeType> to
> a string. We also will want to define the format, because sometimes, we'll
> want to concat a number in decimal representation, sometimes in
> hexadecimal, octal, etc. I think, these conversion functions should write
> to a string view. e.g.:
> template <> // the default conversion for this type
> void boost::cat::convert<complex<...>>(std::string_view& output,
> size_t max_length,
> const complex<...>& data);
> We could use parameters to cat to define conversion functions.
> auto myString = (cat(hex<int>) + 42).str();

If you want that kind of formatting I'd really go for

> I am not sure now, if that syntax is so great to define the conversion
> functions. We'll have to discuss.
> Of course there should be an optimized default conversion function for
> cat-objects as well:
> auto myString = (cat() + "Hello"s + " "s + "World! "s + 42 +
> (cat(hex<int>) + " "s + 42)).str();
> Here the outer cat-object would "steal" the values from the inner
> cat-object and use its conversion functions directly with a view on the big
> result string.
> I understand, that the syntax is not 100% what you try to achieve, but I
> still think, that conversion to string should not be directly done on a
> string object. This specific object to do concatenation and conversion
> actually is the key to gain the maximum possible performance, because it
> can delay the actual concatenation and conversion to a point, where all
> necessary information is available.

True, but then we're back again to an append / sprint style function.


Boost list run by bdawes at, gregod at, cpdaniel at, john at