220 36880 <f8f4407b-ecf6-4a4a-b3f6-c65813e3f843@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Mon, 12 Feb 2018 06:56:12 -0800 (PST)
Lines: 464
Approved: news@gmane.org
Message-ID: <f8f4407b-ecf6-4a4a-b3f6-c65813e3f843@isocpp.org>
References: <356d5835-f1bf-4699-94f5-0b2d3d0b9c0e@isocpp.org>
 <CAMD6iD9aT26x8GQHnQL+kuj3Rq8fVQSfYYFtvTnFidkf6jU_ag@mail.gmail.com>
 <25CCF885-86AD-4D51-8F5C-C46376D34DE0@gmail.com> <4890431.TR9UepuQra@tjmaciei-mobl1>
 <CALvx3hac77b6Z=EOWzKqynALi1-352OvY0dnnOer8rN6tfa01g@mail.gmail.com> <1cdb6300-7397-46d7-bce9-62e6e8dac40b@isocpp.org>
 <CAC+0CCOSZHaTA=YPSDU8Add7mE_BYcYPRCmGW8TRPtZhdqL8Hw@mail.gmail.com>
 <4bce681e-e729-4124-9322-69291fdb6678@isocpp.org>
 <f5feb9a0-99d3-433a-ae46-af34c8d00a61@isocpp.org>
 <8e456af5-09c3-461d-8562-30df127e93af@isocpp.org>
 <bd24b702-025a-4b06-976b-559c779851e1@isocpp.org>
 <f63ed807-c5f6-4997-b03f-b4bc16a70982@isocpp.org>
 <28e80709-5ebb-44d2-b26d-22cafd681330@isocpp.org>
 <52b86f0a-b3b9-455f-9d4d-0f6b15192c90@isocpp.org>
 <1e9a5468-6efa-48a2-87ce-6bdb6d5c4e83@isocpp.org>
 <750ecf62-9637-40f4-8585-e3be2780fb46@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_9306_726954476.1518447372737"
X-Trace: blaine.gmane.org 1518447262 15473 195.159.176.226 (12 Feb 2018 14:54:22 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 12 Feb 2018 14:54:22 +0000 (UTC)
Cc: florian.csdt@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBDOWQ3KAKGQEGEHXORA@isocpp.org Mon Feb 12 15:54:18 2018
Return-path: <std-proposals+bncBCEKFTV6ZUMBBDOWQ3KAKGQEGEHXORA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f71.google.com ([209.85.213.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBDOWQ3KAKGQEGEHXORA@isocpp.org>)
	id 1elFUf-0003Jl-Gx
	for gclcip-std-proposals@m.gmane.org; Mon, 12 Feb 2018 15:54:10 +0100
Original-Received: by mail-vk0-f71.google.com with SMTP id y11sf3737691vkd.11
        for <gclcip-std-proposals@m.gmane.org>; Mon, 12 Feb 2018 06:56:15 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=eX3azFsY3ALqf6oFqgrxerrp1ykeRIvx9tqqpIqmitc=;
        b=uZaDKKkZ3XYOlUiA7W3t5pdTVe4oeXbVP+V5Zeur+7Pn9r+uMiKuG7NoQbGEGakwUZ
         gq3f1HS3dAAa4WOqy8BjDFJg5GrupzZEZJjC/lhJiaFLhs2ZFoWXSX4N7Y3TRDKycXxW
         IYkKwwFXgT2ExLkBsot66uK5Ok6oykbovvW3K/ZUCSYonIEPCfPm0ZMvcRnAJLinVKBG
         CVl+RVfqC9wm2y2bCJjv3ZTyfEt16W5XK6G7xhBIfZW5+9S9arBNHgm6smUx0QDZUTJD
         WE+30kr36nu/JUgENLQgXQKjGz/xq1KVzc+iHQ98WFfRfTk2ZwTXSrzz7NgPHXOysy9o
         LA9w==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=eX3azFsY3ALqf6oFqgrxerrp1ykeRIvx9tqqpIqmitc=;
        b=cS6quFsKQzoeinbwynTgjnG9ektqFNwIyG+oTORgX6JKvjwmXozhHJyrk9N+H5uuXm
         8wbP5CaWPoPYtm+gHuszceZtq15weYzhbYqG7aO7Awvb9mReosT697CKD7Hhv8yxXLi/
         guuRrIIICltzjTjQyzKbc9WtMoBZwFhbU/JIyor7VZNpbratlnfgRl0niHS4qLerJABt
         088UcTt0mz36syHdnn+3Gz8f+R8UMWZnF1fyjkBt49DEr+3viqzdcRvq+p0xHC5u4unw
         wFJW7HUtgCZnw2va3y5piVPhU8CpJwwdCAebIQD2wY4N4gZYQi6zew0jT2wncUQyhqbg
         PS2Q==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post
         :list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=eX3azFsY3ALqf6oFqgrxerrp1ykeRIvx9tqqpIqmitc=;
        b=J7glIuFvOOCdg2Lqz45N3y+HDidRCkMKMsTdKssTtjirfqpTq6c6P9ZxnPy51/4aC8
         PngpVCvJPr/XTQwfHKdpwVzrL2uiQnVeboGkhFBK6XgyFmAJ0Zzc++HnneCz0E3ve0Wz
         X4CmKmBkbZrPJa3f58JZP2avLO2IhGmENHqukfmWPA1lB/IHv1+NnER9LNti5qqntDqE
         Ks1hiK/zmePOcCS1RPp89xBioJdUp1zNdqswjWeIOf+/Dw+9Nh5O109926lsC7wKr2Vl
         zKlJPU+QUuDLgjYjPDK/wgus5oar7aKiUIF6daEBnhDnaQrRDSMKkoMvLqzdsjKsrvKA
         DUVA==
X-Gm-Message-State: APf1xPBRNNosITuvCAPu6jdmoj2rulvtBVsPZUuhz3HkjX/yLp8k83s3
	H97e7pu1psP83H6aCNL0AY+//Q==
X-Google-Smtp-Source: AH8x225XS6gW4FBd8UkEvInOjysO+FJbLy0tCq6Rjkz5kD/7bCQWyy5o0Kvh/sCMnyvjmQ9tOcA1QQ==
X-Received: by 10.31.224.199 with SMTP id x190mr6126997vkg.90.1518447375080;
        Mon, 12 Feb 2018 06:56:15 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.164.68 with SMTP id n65ls7122282vke.0.gmail; Mon, 12 Feb
 2018 06:56:13 -0800 (PST)
X-Received: by 10.31.128.137 with SMTP id b131mr1062546vkd.7.1518447373303;
        Mon, 12 Feb 2018 06:56:13 -0800 (PST)
In-Reply-To: <750ecf62-9637-40f4-8585-e3be2780fb46@isocpp.org>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:36880
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36880>

------=_Part_9306_726954476.1518447372737
Content-Type: multipart/alternative; 
	boundary="----=_Part_9307_1016462171.1518447372739"

------=_Part_9307_1016462171.1518447372739
Content-Type: text/plain; charset="UTF-8"

On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria...@gmail.com wrote:
>
> Let me suggest something close to Nicol's solution, but not quite.
>
> The F"" operator returns a special type that could be like a simple tuple 
> (let's name it std::string_processing for now).
>
> Then the user can use it directly into its own functions.
>
>
> auto column = "col"s;
> auto table = "tab"sv;
> auto req = sql(F"select {column} from {table};");
>
> // would be equivalent to:
> auto req = sql(std::string_processing<const char[8]&, std::string&, const 
> char[7]&, std::string_view&, const char[2]&>("select ", column, " from ", 
> table, ";"));
>
> Now, if we want, we could also support UDL (but not mandatory) by allowing 
> to call UDL on the std::string_processing:
>
> auto column = "col"s;
> auto table = "tab"sv;
> auto req = F"select {column} from {table};"_sql;
>
> // would be equivalent to:
> auto req = operator ""_sql (std::string_processing<const char[8]&, std::
> string&, const char[7]&, std::string_view&, const char[2]&>("select ", 
> column, " from ", table, ";"));
>
> Now let's have some examples of it could be:
>
> Simple string concatenation would be simple
> auto concatenated = F"{str1}{str2}{str3}"s;
> // converted into an efficient concatenation of the 3 strings
>
> We could print it into an iostream if we want (but would be here only for 
> convenience on legacy code)
> std::cout << F"{str1}{str2}\n";
> // equivalent to:
> std::cout << str1 << str2 << "\n";
>
> It could be implicitly convertible to a std::string (only if variables are 
> implicitly convertible to std::string)
> std::string concatenated = F"{str1}{str2}";
>
> (No example with FMT as I don't know how it works, but I don't see any 
> reason for it not to be compatible with FMT.)
>
> And this would be constexpr-able.
>
> Now, formatting would require a bit more elaborated type that could store 
> formatting information.
> But in the end, only the user will know what to do with it.
> However, I would prefer *not* to embed formatting in such a type, just to 
> keep it simple. And use a library based solution when I really need 
> formatting.
>
> It has all the advantages of Nicol's solution, while being more versatile.
>

I fail to see the versatility here, and it does not have all of the 
advantages of my method.

Remember, in my version, UDLs only apply to the string fragments. In your 
version, you *cannot* apply UDLs to string fragments; the string fragments 
will be packed into your `string_processing` type as views or some such.

Then there's ease of use. Let's see how to implement stream-based string 
concatenation with my method:

template<typename ...Args>
auto concat(Args ...&&args)
{
  std::ostringstream stream;
  stream << ... << std::forward<Args>(args);
  return std::move(stream).get();
}

Simple and obvious, a standard bit of C++17 variadic template programming.

Now, how would you go about doing that with `string_processing`? That would 
require template metaprogramming:

template<typename ...Args, size_t ...Ints>
void concat_items(std::ostringstream &stream, std::string_processing<Args
....> &&proc, std::index_sequence<Ints...>)
{
  stream << ... << get<Ints>(proc));
}

template<typename ...Args>
auto concat(std::string_processing<Args...> &&proc)
{
  std::ostringstream stream;
  concat_items(stream, std::move(proc), std::make_index_sequence<size...(
Args)>{});
  return std::move(stream).get();
}

This isn't the hardest code to write in the world, but it is much more 
complex than the previous one. Also, perfect forwarding doesn't really work 
here.

Also, the variadic version of `concat` can be used with stuff that isn't 
the result of string interpolation. Or with multiple interpolated strings. 
And so forth. Whereas your `string_processing` type is a magic type that 
only the compiler can create. And we already have a type that does what 
`string_processing` does; it's called `tuple`.

The *only advantage* your method has over mine is that it allows UDLs to 
define the aggregation operation. Why is this so important to so many 
people?

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843%40isocpp.org.

------=_Part_9307_1016462171.1518447372739
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, February 12, 2018 at 5:17:45 AM UTC-5, floria..=
..@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">Let me suggest something close to Nicol&#39;s solution, but not quite.=
<br><br>The F&quot;&quot; operator returns a special type that could be lik=
e a simple tuple (let&#39;s name it std::string_processing for now).<br><br=
>Then the user can use it directly into its own functions.<br><br><br><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px"><code><div><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> column </span><span style=3D"color:#66=
0">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">=
&quot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"col=
or:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#008">auto</span><span style=3D"color:#000"> table </span><span style=3D"c=
olor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span sty=
le=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> sql</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;select {column} from {table};&quot;</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"><br><br></span><span style=
=3D"color:#800">// would be equivalent to:</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> req </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> sql</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>std</span><span style=3D"color:#660">::</span><span style=3D"color:#000">s=
tring_processing</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#008">con<wbr>st</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#008">char</span><span style=3D"color:#660">[</span><span style=
=3D"color:#066">8</span><span style=3D"color:#660">]&amp;,</span><span styl=
e=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#008">string</span><span style=3D"color:#660">&amp;,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">char</span><span sty=
le=3D"color:#660">[</span><span style=3D"color:#066">7</span><span style=3D=
"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">string_view</span><spa=
n style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">const</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#008">char</span><span style=3D"color:#660">[</span><span s=
tyle=3D"color:#066">2</span><span style=3D"color:#660">]&amp;&gt;(</span><s=
pan style=3D"color:#080">&quot;select &quot;</span><span style=3D"color:#66=
0">,</span><span style=3D"color:#000"> column</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&=
quot; from &quot;</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> table</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot;;&quot;</span><span sty=
le=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></c=
ode></div><br>Now, if we want, we could also support UDL (but not mandatory=
) by allowing to call UDL on the std::string_processing:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> column </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&qu=
ot;col&quot;</span><span style=3D"color:#000">s</span><span style=3D"color:=
#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#0=
08">auto</span><span style=3D"color:#000"> table </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080">&quot;tab&quot;</span><span style=3D"color:#000">sv</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">auto</span><span style=3D"color:#000"> req </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#080">&quot;select {column} from {table};&quot;</span><span style=
=3D"color:#000">_sql</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">// would be equiv=
alent to:</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> req </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#=
008">operator</span><span style=3D"color:#000"> </span><span style=3D"color=
:#080">&quot;&quot;</span><span style=3D"color:#000">_sql </span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">string_processing</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">const</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">char</span=
><span style=3D"color:#660">[</span><span style=3D"color:#066">8</span><spa=
n style=3D"color:#660">]&amp;,</span><span style=3D"color:#000"> std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#008">string</span=
><span style=3D"color:#660">&amp;,</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">const</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">char</span><span style=3D"color:#660">[</span><s=
pan style=3D"color:#066">7</span><span style=3D"color:#660">]&amp;,</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">string_view</span><span style=3D"color:#660">&amp;=
,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">const=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">char</=
span><span style=3D"color:#660">[</span><span style=3D"color:#066">2</span>=
<span style=3D"color:#660">]&amp;&gt;(</span><span style=3D"color:#080">&qu=
ot;select &quot;</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> column</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#080">&quot; from &quot;</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> table</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;;&quot;</span><span style=3D"color:#660">));</span>=
<span style=3D"color:#000"><br></span></div></code></div><br>Now let&#39;s =
have some examples of it could be:<br><br>Simple string concatenation would=
 be simple<br><div style=3D"background-color:rgb(250,250,250);border-color:=
rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> concatenated </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}{str3}&quot;</span><span style=
=3D"color:#000">s</span><span style=3D"color:#660">;</span><span style=3D"c=
olor:#000"><br></span><span style=3D"color:#800">// converted into an effic=
ient concatenation of the 3 strings</span><span style=3D"color:#000"><br></=
span></div></code></div><br>We could print it into an iostream if we want (=
but would be here only for convenience on legacy code)<br><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px"><code><div><span style=3D"color:#000">std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><spa=
n style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> F</span><=
span style=3D"color:#080">&quot;{str1}{str2}\n&quot;</span><span style=3D"c=
olor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#800">// equivalent to:</span><span style=3D"color:#000"><br>std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">cout </span><=
span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000"> str1 <=
/span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color:#000">=
 str2 </span><span style=3D"color:#660">&lt;&lt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#080">&quot;\n&quot;</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div></code>=
</div><br>It could be implicitly convertible to a std::string (only if vari=
ables are implicitly convertible to std::string)<br><div style=3D"backgroun=
d-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;b=
order-width:1px"><code><div><span style=3D"color:#000">std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#008">string</span><span sty=
le=3D"color:#000"> concatenated </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> F</span><span style=3D"color:#080">&quot;{str1=
}{str2}&quot;</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br></span></div></code></div><br>(No example with FMT as I don&#39;=
t know how it works, but I don&#39;t see any reason for it not to be compat=
ible with FMT.)<br><br>And this would be constexpr-able.<br><br>Now, format=
ting would require a bit more elaborated type that could store formatting i=
nformation.<br>But in the end, only the user will know what to do with it.<=
br>However, I would prefer <b>not</b> to embed formatting in such a type, j=
ust to keep it simple. And use a library based solution when I really need =
formatting.<br><br>It has all the advantages of Nicol&#39;s solution, while=
 being more versatile.<br></div></blockquote><div><br>I fail to see the ver=
satility here, and it does not have all of the advantages of my method.<br>=
<br>Remember, in my version, UDLs only apply to the string fragments. In yo=
ur version, you <i>cannot</i> apply UDLs to string fragments; the string fr=
agments will be packed into your `string_processing` type as views or some =
such.<br><br>Then there&#39;s ease of use. Let&#39;s see how to implement s=
tream-based string concatenation with my method:<br><br><div style=3D"backg=
round-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-s=
tyle: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pretty=
print"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">template</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">...</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 concat</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">...&amp;&amp;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">ostringstream stream</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 stream </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">forward</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span =
style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">args</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">stre=
am</span><span style=3D"color: #660;" class=3D"styled-by-prettify">).</span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">get</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><br>Sim=
ple and obvious, a standard bit of C++17 variadic template programming.<br>=
<br>Now, how would you go about doing that with `string_processing`? That w=
ould require template metaprogramming:<br><br><div style=3D"background-colo=
r: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: soli=
d; border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">...</span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> si=
ze_t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Ints</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> concat_items</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">ostringstream </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">stream</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">string_p=
rocessing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">proc</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">index_sequence</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Ints</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...&gt;)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 stream </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Ints</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">proc</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">template</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> concat</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">string_pr=
ocessing</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&l=
t;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">...&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">proc</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">ostringstream stream</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 concat_items</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">stream</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">proc</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">make_index_sequence</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">size</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...(</span><span style=3D"color: #606;" class=3D"st=
yled-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)&gt;{});</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">stream</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">).</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></div></code></div><br>This isn&#39;t the h=
ardest code to write in the world, but it is much more complex than the pre=
vious one. Also, perfect forwarding doesn&#39;t really work here.<br><br>Al=
so, the variadic version of `concat` can be used with stuff that isn&#39;t =
the result of string interpolation. Or with multiple interpolated strings. =
And so forth. Whereas your `string_processing` type is a magic type that on=
ly the compiler can create. And we already have a type that does what `stri=
ng_processing` does; it&#39;s called `tuple`.<br><br>The <i>only advantage<=
/i> your method has over mine is that it allows UDLs to define the aggregat=
ion operation. Why is this so important to so many people?<br></div><br></d=
iv>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8f4407b-ecf6-4a4a-b3f6-c65813e3f843=
%40isocpp.org</a>.<br />

------=_Part_9307_1016462171.1518447372739--

------=_Part_9306_726954476.1518447372737--

.
