220 36887 <d26b85c2-707b-49a5-a007-617027506dd1@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: florian.csdt@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Mon, 12 Feb 2018 09:43:41 -0800 (PST)
Lines: 488
Approved: news@gmane.org
Message-ID: <d26b85c2-707b-49a5-a007-617027506dd1@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>
 <f8f4407b-ecf6-4a4a-b3f6-c65813e3f843@isocpp.org>
 <5b5435db-772e-4c38-8867-f6fbc66d7cec@isocpp.org>
 <5c51d89a-54b6-490b-87f2-09ed263d8322@isocpp.org>
 <305b7669-0744-473e-9715-807b7e8051b6@isocpp.org>
 <0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_830_784042793.1518457421315"
X-Trace: blaine.gmane.org 1518457308 15281 195.159.176.226 (12 Feb 2018 17:41:48 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 12 Feb 2018 17:41:48 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC26HM4V3MIRBTVEQ7KAKGQEH43Y5JY@isocpp.org Mon Feb 12 18:41:44 2018
Return-path: <std-proposals+bncBC26HM4V3MIRBTVEQ7KAKGQEH43Y5JY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f199.google.com ([209.85.217.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC26HM4V3MIRBTVEQ7KAKGQEH43Y5JY@isocpp.org>)
	id 1elI6k-0003Qj-Rc
	for gclcip-std-proposals@m.gmane.org; Mon, 12 Feb 2018 18:41:39 +0100
Original-Received: by mail-ua0-f199.google.com with SMTP id r30sf6376932uag.9
        for <gclcip-std-proposals@m.gmane.org>; Mon, 12 Feb 2018 09:43:44 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to: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=A3aQu1ZPoYQHn/wVGtLLqwyupG2H7lZeTlK38nKUfgw=;
        b=gRzJjyx6yK/hn4bRAeoyGuu/KI+bI4ierS+S2p3SAc9WJkomDf7oGUGkDFp7Rm+3XX
         OheDHPppcUlf5z3NsM0jSIDvZ7ksYnw0fgK0wK/zIMa3vsSZqmO6MnocRD6lxIZ1cjth
         rG00b+RIlFqG8wl1s0DThJxjOLijIGXHIt9B+LXID8FmNQThTidL3GpGH3tGmyKWorvL
         VhYLyl8iO3Ij/HergU8S5p9YNqg618EuiZh9tpFLhmu5A2+MNwhlOHZWdMOh/ZeRCGsU
         T3Ef4QD4XhVsPYQmhMBsQutmevJqIRMAwviiArSNP68WmPmHseQSaT2NM3wa/QUip74j
         Vqyg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to: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=A3aQu1ZPoYQHn/wVGtLLqwyupG2H7lZeTlK38nKUfgw=;
        b=Fn4UIw/30XumgczwQ/S1UX0ouGX479sKaOBz2297My0rgoEV6odGTBO1nq9ZREMK5k
         9k+BTOVt/S+8PIeSZF+eBcH0is6TXwPXa6iFe9GKg1c5aYyaGfkJDebSnNSvZD0j9tdO
         keh17yA+fGzovtggqvBt6HMnBWbejjK+XGyzGEqWwcm1orSV6gRm7m8oMpWtrJ189eXG
         17N5poDilx++wzJnVTFF4SB0MIsHBuSQf9dABgB+dtwzodL69kDRNWR2nd5pNzniqw+k
         2ms2R8NWAYE+39tmMoGBaF2xCFqoXOVupd3Ju3P3UZGapbgoE7cll6X1ASrdi1BOudvz
         rVEQ==
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: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=A3aQu1ZPoYQHn/wVGtLLqwyupG2H7lZeTlK38nKUfgw=;
        b=cgaAYAZ39BpKAf9f7iuwpq4pwSjn11tAkOoLB/u2p3cjV9PtklWPViKdTCibt9vFhw
         aWo1dLgmgbUH+aD9j+XWVEPQAJzC2JYSLKVLbhKGIOgZmMpss4UtIC90ct7B7HVbrkZ2
         poCJMvvSNCU53bNKYMxY/Dn07kZsl3UOIPrx5pORDZXiowdwtkrvGG1G9mpGm4ppDvNL
         JXpLi3NERPfriAUx4AhbF27EpxDTgEZf6y/mShX6WlLGZsxZT45gz+kj6ueTwim4V4Um
         HrX4VFLWMdY2E13yZHIHjPuFH+3++Jtfug+KEb8wf/uoLn+Q1hZm0F3d5+FqUZR7w+ad
         3WzA==
X-Gm-Message-State: APf1xPBcnpxNUcv3jngqGJG/SI+sA21VGuCQsyupNjdDXSytWz2QebBm
	2st0INQeD8vHcWR38adwLf5KFg==
X-Google-Smtp-Source: AH8x227s+9nnycyeqMJzsLuZ3zLTrOp7dffAS3vrJUbs6TSBs+W7tmxIkYs35l+d/gapGvbfQZUYiQ==
X-Received: by 10.31.135.16 with SMTP id j16mr6420303vkd.67.1518457423605;
        Mon, 12 Feb 2018 09:43:43 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.7.13 with SMTP id 13ls7228702vkh.12.gmail; Mon, 12 Feb 2018
 09:43:42 -0800 (PST)
X-Received: by 10.31.178.206 with SMTP id b197mr1104595vkf.11.1518457421753;
        Mon, 12 Feb 2018 09:43:41 -0800 (PST)
In-Reply-To: <0ceb2063-d7b6-4cb8-8c5c-c63aceb5b549@isocpp.org>
X-Original-Sender: florian.csdt@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:36887
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36887>

------=_Part_830_784042793.1518457421315
Content-Type: multipart/alternative; 
	boundary="----=_Part_831_1164484456.1518457421316"

------=_Part_831_1164484456.1518457421316
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nicol Bolas a =C3=A9crit :
>
> On Monday, February 12, 2018 at 11:15:33 AM UTC-5, floria...@gmail.com=20
> wrote:
>>
>> Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit :
>>>
>>> And sadly, none of them have advanced or even received additional=20
>>> revised proposals. My way works just fine with C++ as it is.
>>>
>>> And even if we had that, most use-cases you don't need to pass the=20
>>> values around as a collective object. And if you did, you can make one=
=20
>>> trivially, as above.
>>>
>>> And again, it still doesn't deal with the fact that you lose perfect=20
>>> forwarding.
>>>
>> =20
>> I understand your point about creating a tuple from a parameter pack to=
=20
>> be able to do what is natural with my proposal. Fair enough.
>>
>> However, I don't see how we lose perfect forwarding. I mean, if the=20
>> variable is a lvalue, it is stored as an lvalue reference, and if it is =
a=20
>> rvalue, it is stored as an rvalue reference.
>> This would be the exact same rules as for std::forward_as_tuple.
>>
>
> So what does `get` return? How do you use `get` such that it returns an=
=20
> rvalue reference or lvalue reference appropriately?
>
> Also, by using `forward_as_tuple` for your basis of implementation, you=
=20
> make something as simple as this:
>
> auto val =3D F"interpolate {5}";
>
> Into a dangling reference. If we allow more than just variable names in=
=20
> interpolation, then the expressions can be prvalues, and the lifetimes of=
=20
> any temporaries they manifest will work the way regular C++ works. Since=
=20
> they're bound to the parameters of an object consturctor, their lifetimes=
=20
> end with the termination of the expression. So `val` will reference a=20
> destroyed `int`.
>
> You'd have to start playing games like braced-init-lists do when they=20
> manifest an `initializer_list` to fix this.
>
> I'd rather make that a straight-up error and force you to explicitly stic=
k=20
> such things in a specific type.
>

I would say it's the same problem as:
auto&& i =3D 5;

But yes, returning a parameter pack forbids that kind of use and avoid=20
dangling references. I agree.
=20

>
>
>>> With that in mind, the implementation of your concat function with my=
=20
>>>> approach would be exactly the same as with your approach (with a call =
to=20
>>>> "operator..." of std::string_processing ).
>>>>
>>>> And then, with only c++17 metaprogramming capabilities, you could also=
=20
>>>> use std::apply.
>>>>
>>>
>>> You cannot `apply` things to operators. Not without creating a lambda=
=20
>>> function that gets called with it.
>>>
>> =20
>> Why not? You can get the address of an operator, and this is a callable=
=20
>> object.
>>
>
> You can only get the address of a single overload of an operator.=20
> Remember: the whole idea is that you're dealing with a sequence of=20
> variables of different types. So the second parameter to the operator has=
=20
> to be of different types for different invocations of the operator.
>

This is another quirk of C++ that should be fixed.
=20

>
> The fact is, it's a *lot* easier in C++ as it currently stands to go from=
=20
>>> parameter pack of values to an object than it is to go from an object t=
o a=20
>>> parameter pack of values. I wish that were not the case, but so long as=
 it=20
>>> is the case, parameter packs will remain the easier-to-use option.
>>>
>> =20
>> You have a point.=20
>>
>>
>>> UDL the aggregate is not important to me, but it was easy to include an=
d=20
>>>> allows neat syntax (in my opinion).
>>>>
>>>
>>> But it makes it impossible to apply a UDL to the string fragments. And=
=20
>>> that's important if you do want to use template metaprogramming on stri=
ng=20
>>> literals.
>>>
>>
>> I'm not sure to see the use case here. When you use UDL, you want the=20
>> whole literal to be what you say it would be.
>> auto s =3D "something"s; // s is a string
>> auto sv =3D "some other"sv; // s is a string view
>> We are not interested in what is happening in the middle. I don't why it=
=20
>> should be different with string interpolation (or whatever the name is).
>>
>
> Because not all of the "literal" is actually a literal anymore. That's th=
e=20
> whole point of string interpolation: you're taking a literal and you're=
=20
> augmenting it with some non-literal data. Potentially *runtime*=20
> non-literal data. It isn't a literal anymore, so the UDL suffix can't app=
ly=20
> to the aggregate. It can only apply to the individual literal fragments o=
f=20
> the string.
>

Here, I don't care if it's called a literal, or if we invent a new name for=
=20
this concept that appeared to match the concept of literal when "string=20
interpolation" was not a thing.
I'm more interested in the final syntax as the end user will see it.

And I would prefer concatenate like this:
auto s =3D F"{str1}{str2}{str3}"s;
than this:
auto s =3D std::concat(F"{str1}{str2}{str3}");

The first one looks more natural in my opinion.

=20

>
> Also, remember: you cannot apply a UDL suffix to a `constexpr` string=20
> value. So again, if we ever want to apply interpolation to `constexpr`=20
> strings, then we need to have an invocation syntax that doesn't encourage=
=20
> people to use UDLs for them.
>

F"something" looks like a string literal, so it would be natural to have a=
=20
similar syntax.
And I don't think allowing this would encourage people to use UDL-like=20
syntax to do constexpr string computation that are not related to "string=
=20
interpolation".
=20

>
> And with my proposal, you can always apply a function to every single=20
>> element, and this function can be a UDL if you really want.
>>
>>
>> To sum up, F"something" returning a parameter pack is probably the way t=
o=20
>> go because of the current C++, but would not bring that much with a prop=
er=20
>> C++.
>>
>
> I don't agree with that. Even if we had P0535, it's still easier to work=
=20
> with the arguments as a pack than it is to turn an object into a pack.=20
> P0535 lowers the bar into the "reasonable" range, but 9 times out of 10,=
=20
> just taking the parameters as a pack rather than unpacking an object will=
=20
> be easier.
>
> Using a pack also handily deals with the lifetime issues for prvalues, if=
=20
> we allow arbitrary expressions in interpolated strings.
>

I got your point, and, after thinking about it, I agree with you.
=20

>
> Also, let's not forget the other things I mentioned. That=20
> `string_processing` would have to be a magic type created only by the=20
> compiler like `initializer_list`. Which means you cannot call one of the=
=20
> aggregation functions with your own parameters; they would be explicitly=
=20
> bound to using string interpolation. By contrast, if you're just using=20
> regular functions with variadic arguments, you can call them yourself=20
> without invoking string interpolation.
>
> That makes my version more flexible.
>
> And then, I think UDL should apply to the whole stuff and not its part.
>>
>
> So how do you apply a UDL to just the string literal fragments? Without=
=20
> creating a bunch of pointless variables, which is the antithesis of the=
=20
> whole idea of interpolation.
>

> The point of that discussion was a comment someone made about doing=20
> template metaprogramming on string literals. To do that, you need a way t=
o=20
> access each literal as a distinct type, some `string_literal<char, 'c',=
=20
> 'h', 'a', 'r'>` type. And only a UDL applied to each fragment can perform=
=20
> that kind of synthesis.
>
>
If we had proper string literals in c++, this would never have been a=20
problem. The same applies to proper constexpr functions (like overloadable=
=20
by constexpr-ness or requiring some inputs to be constexpr).

--=20
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 e=
mail 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/d26b85c2-707b-49a5-a007-617027506dd1%40isocpp.or=
g.

------=_Part_831_1164484456.1518457421316
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 12 f=C3=A9vrier 2018 17:56:48 UTC+1, Nico=
l Bolas a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">On Monday, February 12, 2018 at 11:15:33 AM UTC-5, <a>floria.=
...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr">Le lundi 12 f=C3=A9vrier 2018 16:45:41 UTC+1, Nicol Bolas a =C3=A9crit=
=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">And sadly, =
none of them have advanced or even received additional revised proposals. M=
y way works just fine with C++ as it is.<br><div><br>And even if we had tha=
t, most use-cases you don&#39;t need to pass the values around as a collect=
ive object. And if you did, you can make one trivially, as above.<br><br>An=
d again, it still doesn&#39;t deal with the fact that you lose perfect forw=
arding.<br></div></div></blockquote><div>=C2=A0</div><div>I understand your=
 point about creating a tuple from a parameter pack to be able to do what i=
s natural with my proposal. Fair enough.</div><div><br></div><div>However, =
I don&#39;t see how we lose perfect forwarding. I mean, if the variable is =
a lvalue, it is stored as an lvalue reference, and if it is a rvalue, it is=
 stored as an rvalue reference.</div><div>This would be the exact same rule=
s as for std::forward_as_tuple.</div></div></blockquote><div><br>So what do=
es `get` return? How do you use `get` such that it returns an rvalue refere=
nce or lvalue reference appropriately?<br><br>Also, by using `forward_as_tu=
ple` for your basis of implementation, you make something as simple as this=
:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(1=
87,187,187);border-style:solid;border-width:1px"><code><div><span style=3D"=
color:#008">auto</span><span style=3D"color:#000"> val </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span><span style=
=3D"color:#080">&quot;interpolate {5}&quot;</span><span style=3D"color:#660=
">;</span></div></code></div><br>Into a dangling reference. If we allow mor=
e than just variable names in interpolation, then the expressions can be pr=
values, and the lifetimes of any temporaries they manifest will work the wa=
y regular C++ works. Since they&#39;re bound to the parameters of an object=
 consturctor, their lifetimes end with the termination of the expression. S=
o `val` will reference a destroyed `int`.<br><br>You&#39;d have to start pl=
aying games like braced-init-lists do when they manifest an `initializer_li=
st` to fix this.<br><br>I&#39;d rather make that a straight-up error and fo=
rce you to explicitly stick such things in a specific type.<br></div></div>=
</blockquote><div><br></div><div>I would say it&#39;s the same problem as:<=
/div><div><div style=3D"background-color: rgb(250, 250, 250); border-color:=
 rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap:=
 break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">5</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span></div></code></div><br>But yes, r=
eturning a parameter pack forbids that kind of use and avoid dangling refer=
ences. I agree.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote"=
 style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>With that in mind, the implementation of your concat=
 function with my approach would be exactly the same as with your approach =
(with a call to &quot;operator...&quot; of std::string_processing ).</div><=
div><br></div><div>And then, with only c++17 metaprogramming capabilities, =
you could also use std::apply.<br></div></div></blockquote><div><br>You can=
not `apply` things to operators. Not without creating a lambda function tha=
t gets called with it.<br></div></div></blockquote><div>=C2=A0</div><div>Wh=
y not? You can get the address of an operator, and this is a callable objec=
t.</div></div></blockquote><div><br>You can only get the address of a singl=
e overload of an operator. Remember: the whole idea is that you&#39;re deal=
ing with a sequence of variables of different types. So the second paramete=
r to the operator has to be of different types for different invocations of=
 the operator.<br></div></div></blockquote><div><br></div><div>This is anot=
her quirk of C++ that should be fixed.<br></div><div>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div>The fact is, it&#39;s a <i>l=
ot</i> easier in C++ as it currently stands to go from parameter pack of va=
lues to an object than it is to go from an object to a parameter pack of va=
lues. I wish that were not the case, but so long as it is the case, paramet=
er packs will remain the easier-to-use option.<br></div></div></blockquote>=
<div>=C2=A0</div><div>You have a point. <br></div><div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
 #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div>UDL the a=
ggregate is not important to me, but it was easy to include and allows neat=
 syntax (in my opinion).<br></div></blockquote><div><br>But it makes it imp=
ossible to apply a UDL to the string fragments. And that&#39;s important if=
 you do want to use template metaprogramming on string literals.<br></div><=
/div></blockquote><div><br></div><div>I&#39;m not sure to see the use case =
here. When you use UDL, you want the whole literal to be what you say it wo=
uld be.</div><div><div style=3D"background-color:rgb(250,250,250);border-co=
lor:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span =
style=3D"color:#008">auto</span><span style=3D"color:#000"> s </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&quot;something&quot;</span><span style=3D"color:#000">s<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span=
><span style=3D"color:#800">// s is a string</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#0=
00"> sv </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#080">&quot;some other&quot;</span><span s=
tyle=3D"color:#000">sv</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#800">// s is a string view</s=
pan><span style=3D"color:#000"><br></span></div></code></div>We are not int=
erested in what is happening in the middle. I don&#39;t why it should be di=
fferent with string interpolation (or whatever the name is).<br></div></div=
></blockquote><div><br>Because not all of the &quot;literal&quot; is actual=
ly a literal anymore. That&#39;s the whole point of string interpolation: y=
ou&#39;re taking a literal and you&#39;re augmenting it with some non-liter=
al data. Potentially <i>runtime</i> non-literal data. It isn&#39;t a litera=
l anymore, so the UDL suffix can&#39;t apply to the aggregate. It can only =
apply to the individual literal fragments of the string.<br></div></div></b=
lockquote><div><br></div><div>Here, I don&#39;t care if it&#39;s called a l=
iteral, or if we invent a new name for this concept that appeared to match =
the concept of literal when &quot;string interpolation&quot; was not a thin=
g.</div><div>I&#39;m more interested in the final syntax as the end user wi=
ll see it.</div><div><br></div><div>And I would prefer concatenate like thi=
s:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-col=
or: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-wr=
ap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{str2}{str3=
}&quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">s</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div></div><div>than this:</div><div><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> s </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">c=
oncat</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&quot;{str1}{str2}{str3=
}&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span>=
</div></code></div><br>The first one looks more natural in my opinion.<br><=
/div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
 1ex;"><div dir=3D"ltr"><div><br>Also, remember: you cannot apply a UDL suf=
fix to a `constexpr` string value. So again, if we ever want to apply inter=
polation to `constexpr` strings, then we need to have an invocation syntax =
that doesn&#39;t encourage people to use UDLs for them.<br></div></div></bl=
ockquote><div><br></div><div>F&quot;something&quot; looks like a string lit=
eral, so it would be natural to have a similar syntax.</div><div>And I don&=
#39;t think allowing this would encourage people to use UDL-like syntax to =
do constexpr string computation that are not related to &quot;string interp=
olation&quot;.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div></div><div></div><div>And with my proposal, y=
ou can always apply a function to every single element, and this function c=
an be a UDL if you really want.</div><div><br></div><div><br></div><div>To =
sum up, F&quot;something&quot; returning a parameter pack is probably the w=
ay to go because of the current C++, but would not bring that much with a p=
roper C++.</div></div></blockquote><div><br>I don&#39;t agree with that. Ev=
en if we had P0535, it&#39;s still easier to work with the arguments as a p=
ack than it is to turn an object into a pack. P0535 lowers the bar into the=
 &quot;reasonable&quot; range, but 9 times out of 10, just taking the param=
eters as a pack rather than unpacking an object will be easier.<br><br>Usin=
g a pack also handily deals with the lifetime issues for prvalues, if we al=
low arbitrary expressions in interpolated strings.<br></div></div></blockqu=
ote><div><br></div><div>I got your point, and, after thinking about it, I a=
gree with you.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div><br>Also, let&#39;s not forget the other t=
hings I mentioned. That `string_processing` would have to be a magic type c=
reated only by the compiler like `initializer_list`. Which means you cannot=
 call one of the aggregation functions with your own parameters; they would=
 be explicitly bound to using string interpolation. By contrast, if you&#39=
;re just using regular functions with variadic arguments, you can call them=
 yourself without invoking string interpolation.<br><br>That makes my versi=
on more flexible.<br><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div>And then, I think UDL should apply to the whole stuff and=
 not its part.</div></div></blockquote><div><br>So how do you apply a UDL t=
o just the string literal fragments? Without creating a bunch of pointless =
variables, which is the antithesis of the whole idea of interpolation.</div=
></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br>The point of that discussion was a comment someone made about =
doing template metaprogramming on string literals. To do that, you need a w=
ay to access each literal as a distinct type, some `string_literal&lt;char,=
 &#39;c&#39;, &#39;h&#39;, &#39;a&#39;, &#39;r&#39;&gt;` type. And only a U=
DL applied to each fragment can perform that kind of synthesis.<br><br></di=
v></blockquote><div><br></div><div>If we had proper string literals in c++,=
 this would never have been a problem. The same applies to proper constexpr=
 functions (like overloadable by constexpr-ness or requiring some inputs to=
 be constexpr).<br></div></div>

<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/d26b85c2-707b-49a5-a007-617027506dd1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d26b85c2-707b-49a5-a007-617027506dd1=
%40isocpp.org</a>.<br />

------=_Part_831_1164484456.1518457421316--

------=_Part_830_784042793.1518457421315--

.
