Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Assigning to a literal

38 views
Skip to first unread message

JiiPee

unread,
Apr 20, 2017, 2:33:37 PM4/20/17
to
On 20/04/2017 17:38, Stefan Ram wrote:
> auto string =( "abc"s += "def" );
> ::std::cout << string << '\n';


interesting. good to know. Thanks.

What is the purpose of s after abs? why it needs to be there?

JiiPee

unread,
Apr 20, 2017, 2:34:32 PM4/20/17
to
On 20/04/2017 17:38, Stefan Ram wrote:
> I only now became aware of the fact that in C++
> one now can /assign to a literal/:
>
> "abc"s = "def"s;
>
> . For another example,
>
> auto string =( "abc"s += "def" );
> ::std::cout << string << '\n';
>
> .
>
>

or is it possibly that s creates a temorary string out of abc?

Cholo Lennon

unread,
Apr 20, 2017, 2:52:58 PM4/20/17
to

Alf P. Steinbach

unread,
Apr 20, 2017, 11:02:24 PM4/20/17
to
On 20-Apr-17 6:38 PM, Stefan Ram wrote:
> I only now became aware of the fact that in C++
> one now can /assign to a literal/:
>
> "abc"s = "def"s;
>
> . For another example,
>
> auto string =( "abc"s += "def" );
> ::std::cout << string << '\n';

Readers might justifiably think that this can't have any practical
utility – there's always a more natural way to express whatever…

However, I've used it for string building in function calls, by simply
overloading `operator<<`, e.g. instead of the awkward and inefficient

foo( string() + "6*7 = " + to_string( 6*7 ) + "..." ); // :(

… or the even more awkward and more inefficient

ostringstream stream; // :(
stream << "6*7 = " << 6*7 << "..."; // :(
foo( stream.str() ); // :(

… writing just

foo( "6*7 = "s << 6*7 << "..." ); // Yay! :)

In C++03 there were no user defined literals so one had to write e.g.
`typedef String_builder S; foo( S() << "6*7 = "` ... );`. Which was ugly
& messy, though not as ugly & messy as using the standard library
directly. And now with C++11 user defined literals it's clean.

• • •

In the overloads of `<<` one needs a uniform notation for converting a
value of arbitrary type to string. In C++03 the only support from the
standard library was `std::ostringstream`, which was horribly
inefficient, relatively speaking. So in those times I defined my own
uniform notation, with `std::ostringstream` just as a generic fallback.

C++11 added `std::to_string`, but it lacks overloads for `std::string`
and `char const*`, and for both of these there is a show-stopper, that
one is not allowed to specialize a standard library function on a
non-user-defined type.

C++14 §17.6.4.2.1/2:
“A program may explicitly instantiate a template defined in the
standard library only if the declaration depends on the name of a
user-defined type and the instantiation meets the standard library
requirements for the original template.”

… where “user defined” IMO refers to the user of the library, not
including the standard library code authors as users of C++. In order to
avoid possible clashes between different specializations. I.e. that
`std::string` is not regarded as a user defined type, in this context.

So even with C++11 and later one practically has to define one's own
uniform notation for conversion to string, unless one is happy with the
inefficiency of `std::ostringstream`, which is sort of absurd.

C++17 adds `std::to_chars`, which addresses the dynamic allocation
inefficiency, but it still does not define a uniform notation. :(

• • •

I've implemented this so many times, in slightly different ways, that
I've lost count, but it would be too much work for me (for this posting)
to find some earlier published version, e.g. posted here in clc++. The
most recent manifestation of the beast is a bit unclean in that it has a
library dependency. It's available here:

<ur:
https://github.com/alf-p-steinbach/Expressive-Cpp/blob/master/library_extension/string_builders.hpp>

It's part of my Expressive C++ experimental library, and the
dependencies of the implementation code are only on that library. Still
I think that dependency means that most readers will benefit mostly from
this as an example, a source of ideas, not as code to just copy.


Cheers!,

- Alf

0 new messages