220 36910 <c753942d-be11-4cc0-bde1-7f71b6184367@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Todd Fleming <tbfleming@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: String interpolation
Date: Tue, 13 Feb 2018 17:03:16 -0800 (PST)
Lines: 764
Approved: news@gmane.org
Message-ID: <c753942d-be11-4cc0-bde1-7f71b6184367@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>
 <d26b85c2-707b-49a5-a007-617027506dd1@isocpp.org>
 <41b87b07-1a91-4bca-ba00-5734c09dbe77@isocpp.org>
 <ef8fbc4c-08c0-409e-815b-28e161101231@isocpp.org>
 <1a7f714d-4a91-4a95-8da4-0c688d18c4c4@isocpp.org>
 <5f8efcc0-f4e9-4518-abe5-5fffeab55083@isocpp.org>
 <0e0876bb-7a44-45ff-ab9b-6443e78ea59c@isocpp.org>
 <3468ee0c-a44a-437a-a835-0156c623df2e@isocpp.org>
 <d2698aec-cf41-4787-8aa5-334a34868aea@isocpp.org>
 <589a55c8-d886-4bb1-b991-96c5e9fe910a@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_12615_215957504.1518570196677"
X-Trace: blaine.gmane.org 1518570090 1226 195.159.176.226 (14 Feb 2018 01:01:30 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Wed, 14 Feb 2018 01:01:30 +0000 (UTC)
Cc: florian.csdt@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDN5JUVZSIFBBVUVR3KAKGQEWGTK5FQ@isocpp.org Wed Feb 14 02:01:25 2018
Return-path: <std-proposals+bncBDN5JUVZSIFBBVUVR3KAKGQEWGTK5FQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f197.google.com ([209.85.217.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDN5JUVZSIFBBVUVR3KAKGQEWGTK5FQ@isocpp.org>)
	id 1ellRi-0007mP-CD
	for gclcip-std-proposals@m.gmane.org; Wed, 14 Feb 2018 02:01:14 +0100
Original-Received: by mail-ua0-f197.google.com with SMTP id c40sf9311711uae.18
        for <gclcip-std-proposals@m.gmane.org>; Tue, 13 Feb 2018 17:03:20 -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=9SdzGW+Du9hvKV6S0PIMHR/cgzCot5hnoTWGWD3CPyA=;
        b=FC8QXtZuJxQvUZi5BbCAdH7pIZM/8ZcOsFg7vwQc+azzK4pLPQOgi0VQ6mjnJsV1Kb
         m6CnGLO/96Mj0xMuxg9A4r+shwmm1aFs8Q5ZZsHdHmnU8b8Sm1/TzM3+ajQ65Hq3VQ6k
         c2Fz7r93QdVvmOYEdvNkK48Dhbwi243iOr94A4QmmPm/OLmcZCUV+9LjGkEHS2QEujZQ
         l8JdL55e0Hgqhlz8hV4W9uoB0XvEj+hsM1poDBrMhmwo07iPa1266CWTfgbA9OPjFEZf
         wF8WAItonhGgfc4bnw+UawXtdINXWSNiM9oHwPz4wDB7ZZoeM+UK7Odl/47AfuIiHnoW
         id3w==
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=9SdzGW+Du9hvKV6S0PIMHR/cgzCot5hnoTWGWD3CPyA=;
        b=bydktOEtKYu052F9ZFPVAhlEr27Nsf/N5cc4boiQ/qjs7kTNxHjzPiI4ddsDFrJ3IQ
         wAZvHFo4K0KTZxcNDfUxXKdyK/1SD5Oh+I0/a5GT3drWFuqS0HL6R9l9YMdUnq9Ag+jC
         OrDStsodOxA7z06E6KE+fxV0Qge9VKfWe5Pq0mSJvzKJjLfpMSdYQsr2tkqD03utSb3E
         kDs/Y8b0EUD5484Rg/y1lp3mvXTwbKiSQ5uHADXjSwzmGEK8cE+lSkpRe4ktsFbJTPGt
         ZZLiGTiOuv+qfkTbSe4CT1DXttxsr4MrF6wHlDG7ESfjpyY+Q8RD1LGmPcz0GXEl2Lzx
         tzng==
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=9SdzGW+Du9hvKV6S0PIMHR/cgzCot5hnoTWGWD3CPyA=;
        b=hw1JDNhQQeln7OeoqlbOkl4RlbSoIcpFdlPvn1pHnZFKDDYOph5p/kIW6y1j7K2kmI
         xddkk09r11kpovkQyVbVjPCjJgUyBWTX3g4Ku4vcU9wX+Kvglx2SOd8IlfQ9lbDhg901
         hX1vv0AHFzd+/7dil7YgQMvCgVYDwVq9yFZlsUcR8U8Xlbdx9gkjbBA4+mrK5ICNLrhP
         47Fa2BHjCyf30BQ0yZzBjU27nP/rCWKt/JaNiyotzp2lzAUr3tWFBBxE+imbFE+NNvI9
         dVuMTI7dIRR7o5DsW9BXGEOit0PaO3ZEi/lr1AmFnWdO1D8EBryTBW685Zj4Nwjmkm8/
         2bdQ==
X-Gm-Message-State: APf1xPCtRCUVpzt592Ta3WgNjIIkw2ApOlB2GXyfkXjzg1098qZYb/00
	tEwCjtKrusZUwruYh2OXZ6Ss5g==
X-Google-Smtp-Source: AH8x227WslBGkO8Tv1iA0Ik4qiuGRRIC64HgDX7erHmMxAyyZEusN5+O218hGD+flxtA+Mx/qjtzXg==
X-Received: by 10.176.26.27 with SMTP id a27mr1552770uai.35.1518570199719;
        Tue, 13 Feb 2018 17:03:19 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.16.66 with SMTP id g63ls2285321vki.4.gmail; Tue, 13 Feb
 2018 17:03:18 -0800 (PST)
X-Received: by 10.31.178.206 with SMTP id b197mr269366vkf.11.1518570197539;
        Tue, 13 Feb 2018 17:03:17 -0800 (PST)
In-Reply-To: <589a55c8-d886-4bb1-b991-96c5e9fe910a@isocpp.org>
X-Original-Sender: tbfleming@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:36910
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/36910>

------=_Part_12615_215957504.1518570196677
Content-Type: multipart/alternative; 
	boundary="----=_Part_12616_1502680122.1518570196678"

------=_Part_12616_1502680122.1518570196678
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin Jaczewski wrote:
>
>
>
> On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas wrote:
>>
>> On Tuesday, February 13, 2018 at 12:18:59 PM UTC-5, floria...@gmail.com=
=20
>> wrote:
>>>
>>> Le mardi 13 f=C3=A9vrier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit =
:
>>>>
>>>> Because it would never be called. Basically, what you'd need is this=
=20
>>>> constructor:
>>>>
>>>> template<size_t N>
>>>> string_view(const char s[N]);
>>>>
>>>> But you already have this constructor:
>>>>
>>>> string_view(const char *s);
>>>>
>>>> An array decays into a pointer. And since the pointer constructor is=
=20
>>>> not a template, it is considered a better match than the array version=
.. And=20
>>>> therefore, any ltieral you pass will go through the pointer version ra=
ther=20
>>>> than the array template.
>>>>
>>>> And it should be noted that this has nothing to do with being a=20
>>>> literal. If you used a `const char[]` variable, it *still* would=20
>>>> prefer the pointer version due to array->pointer conversion. So this i=
s not=20
>>>> a case of "string literals are broken now".
>>>>
>>>
>>> How can you say that preferring a lossy conversion over a lossless one=
=20
>>> is not broken? (Here, we lose the length information)
>>>
>>
>> Because the "lossy conversion" part being preferred has nothing to do=20
>> with them being string literals. The lossy conversion is not the=20
>> literal-to-array conversion; it's the array-to-pointer conversion.
>>
>> You're complaining about the wrong problem.
>>
>> This make it impossible to work with string literal because they simply=
=20
>>> don't exist in the language. This is why I said string literals are bro=
ken.
>>> =20
>>>
>>>> But there's no "fix" for this, since any array->pointer "fix" would be=
=20
>>>> both wildly incompatible with C and break tons and tons of code. So yo=
u can=20
>>>> either accept the language and work with what we have, or rail against=
 it.
>>>>
>>>
>>> Ok it's not possible to fix array decay because of backward=20
>>> compatibility, but it is still possible to fix string literals if we ma=
ke=20
>>> them something that is not an array.
>>>
>>
>> Why would changing the behavior of string literals be any more backwards=
=20
>> compatible than changing the behavior of arrays? There's lots of code ou=
t=20
>> there that works with C++'s string literal rules. Can you find a way to=
=20
>> change those rules without breaking their code?
>>
>> Let me give you a simple case: `decltype("a string literal")` is an arra=
y=20
>> type. Therefore, any BC change will have to leave it as an array type. S=
o=20
>> what rules would you change to fix the problem you want fixed without=20
>> changing the result of that `decltype`?
>>
>> So I rail against those defects in order to be heard, and maybe, at some=
=20
>>> point, they will be fixed.
>>>
>>
>> Yeah, that's not how this works. You can "rail against those defects" al=
l=20
>> you like, but unless you're willing to actually work on it (ie: finding =
a=20
>> solution that doesn't break the world and getting it through the=20
>> committee), it will not get fixed. Or you manage to convince someone who=
's=20
>> actually willing to put in said work to do so.
>>
>> If this is not the place to speak out loud about those defects, then=20
>>> where should we go?
>>>
>>> But don't get me wrong, when I code, I work with what I have, and I=20
>>> accept the language as it is.
>>> =20
>>>
>>>>
>>>> It's funny how the more I dig in C++, the more bulky it appears to be=
=20
>>>>> just because of these very small annoyances.
>>>>> =20
>>>>>
>>>>>>
>>>>>> It's a 3 step process; let's not interfere in that.
>>>>>> =20
>>>>>>
>>>>>>> We could have exatcly the situation with string interpolation:
>>>>>>> auto s =3D std::concat(F"{str1}{str2}{str3}");
>>>>>>> // would be equivalent to
>>>>>>> auto s =3D F"{str1}{str2}{str3}"s;
>>>>>>>
>>>>>>> I don't see why allowing UDL to work like that would decrease=20
>>>>>>> usability as we could always use regular functions.
>>>>>>>
>>>>>>
>>>>>> Because you can't do this:
>>>>>>
>>>>>> std::concat(F"some string {variable} other string"sv);
>>>>>>
>>>>>> Under my system, the UDL employed here allows you to decide how to=
=20
>>>>>> process each of the literal fragments. The UDL applies to the parts =
of the=20
>>>>>> literal that are actually strings. So `concat` would get `string_vie=
w`s,=20
>>>>>> rather than `const char[X]` parameters.
>>>>>>
>>>>>> Under your system, the processing of the literal fragments is=20
>>>>>> controlled entirely by the system that computes the aggregation.
>>>>>>
>>>>>
>>>>> Let's sum up, string literals are broken today. So we should probably=
=20
>>>>> try to solve this big issue before trying to see how we can cripple=
=20
>>>>> string_interpolation in order to fit in current-ish C++.
>>>>>
>>>>
>>>> I fail to see why applying a UDL to the literal fragments rather than=
=20
>>>> the interpolation aggregation operation should be considered "cripplin=
g"=20
>>>> string interpolation.
>>>>
>>>> Whatever breakage you see in literals isn't standing in the way of=20
>>>> string interpolation. It's just standing in the way of string interpol=
ation=20
>>>> working the way *you* want it to.
>>>>
>>>
>>> Because string interpolation is dealing with string literals,
>>>
>>
>> Why does it have to be? If constexpr strings are in the future, it'd be=
=20
>> really nice if string interpolation were defined in such a way that it=
=20
>> could be used on them. Tying interpolation to literals is not=20
>> forward-thinking.
>>
>> if those literals are broken (and they are), how can we have a proper=20
>>> string interpolation?
>>>
>>
>> Because any "brokenness" of string literals has no effect on our ability=
=20
>> to use string interpolation. If you want sized strings for those string=
=20
>> fragments, that's what the `sv` suffix is for.
>>
>> Literal issues only are a problem for string interpolation because you=
=20
>> believe that the suffix ought to be able to define the aggregation=20
>> operation. If you stop believing that, then all of a sudden, your proble=
m=20
>> with string literals becomes a non-issue for interpolation.
>>
>> It should also be noted that this:
>>
>> template<typename T>
>> void foo(const T& t);
>>
>> foo("an array");
>>
>> The call to `foo` will deduce `T` to be `char[9]`. So a variadic templat=
e=20
>> function that takes the results of string interpolation will get sized=
=20
>> array types, not pointers.
>>
>> Note that this doesn't invalidate anything I said. The point of doing=20
>> `F"blah {variable} blah"sv` is not necessarily because you need them to=
=20
>> keep the size around. Using `string_view` has many other advantages, wit=
h=20
>> its member functions, `operator<<` overloads, and the like. So wanting t=
o=20
>> apply `sv` to each of the fragments is a perfectly reasonable operation.
>>
>> Also, `string_view` is a lot more convenient to use than an array of=20
>> characters.
>>
>> You said:
>>>
>>>> The point of that discussion was a comment someone made about doing=20
>>>> template metaprogramming on string literals. To do that, you need a wa=
y to=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 perf=
orm=20
>>>> that kind of synthesis.
>>>>
>>>
>>> UDL is the only way to do it only because string literals are broken. I=
f=20
>>> we had proper string literals, it should be possible to do it simply wi=
th=20
>>> regular functions.
>>>
>>
>> No, it would not. Even if a string literal had a non-array type with a=
=20
>> stored size, each literal value would still not have its own distinct=20
>> *type*. Even if the size is a template argument, two literals can store=
=20
>> different characters while still having the same size. And you cannot do=
=20
>> type-based metaprogramming without having a 1:1 mapping between value an=
d=20
>> type.
>>
>> Remember: while UDL's *can* take strings as a sequence of character=20
>> template parameters, there's a good reason why they aren't *required* to=
=20
>> do so. We don't want to force that onto everybody, and a non-"broken"=20
>> string literal system would not force that on people.
>>
>> So even with your approach, broken string literals are a problem for=20
>>> string interpolation. Just not at the same place.
>>>
>>> I'm not sure if my approach is the right one (it's probably not), but=
=20
>>> most of your arguments stand only because string literal are broken=20
>>> (otherwise, it would have been simple to do the same with my approach t=
oo).
>>>
>>> My point is: yes your approach makes it easier with current C++, but we=
=20
>>> shouldn't go for something that works quite well with current C++, but=
=20
>>> something that will work very well with future C++.
>>> That's why I think it's better to first fix string literals. And then=
=20
>>> have string interpolation right the first time.
>>>
>>> And btw, if string literals are fixed, string interpolation could be=20
>>> made a library solution only ( with a different but reasonable syntax).
>>>
>>
>> It's impossible to do that. String interpolation, at its core, is about=
=20
>> taking the contents of a string and applying them in some way to the cod=
e=20
>> *around* that string. A library solution cannot possibly do that.
>>
>> Oh sure, a `constexpr` function could do the parsing. But then what? I'm=
=20
>> fairly certain that no static reflection proposal provides a mechanism t=
o=20
>> turn a string into a reference to a local variable. And even if they did=
,=20
>> the location where you're doing that conversion wouldn't have that varia=
ble=20
>> in scope (since it's in a function call), so it couldn't possibly work.
>>
>> PS: I think it would be preferable to stop the discussion here, as it=20
>>> becomes more and more off-topic.
>>>
>>
>> But what if we don't agree that string interpolation needs better=20
>> literals?
>>
>> Your premise is essentially that my suggested syntax is some kind of=20
>> compromise, that if literals weren't "broken" the way you feel that they=
=20
>> are, then it would *clearly* be correct to have UDLs applied to=20
>> aggregation rather than to the individual fragments.
>>
>> I don't agree with that premise. Whether literals are good or broken is =
a=20
>> side issue. Even if we had perfect literals, I would *still* rather UDLs=
=20
>> be focused on individual string literal manipulation rather than string=
=20
>> interpolation aggregation.
>>
> =20
>
> After some toughs I come to conclusion that mixing interpolation with UDL=
=20
> is limiting thing and this is good thing. Why? Because beside good things=
=20
> it limit bad things too.
> I start from high metaprograming starting point where I made all trader=
=20
> offs to make it work, you start from basic usage and use opposite options=
..
> As consequence all my example of use of string interpolation become=20
> unusable in your approach.
>
> We can start with sql, you suggest that version:
> db.exec(F"some sql stuff {var1} more sql {var2};");
>
> I can quote someone: "Have we learned nothing from Little Bobby Tables?",=
=20
> how you want disquisition between `const char*`s parameters?
> I did not had this problem because I can limit how parameters are pass to=
=20
> UDL and I can relay on it.
> One way to avoid it is add new literal that will help with that but in=20
> some corner cases it could still break.
>
> db.exec("select sth"_sql);
> db.exec(F"select sth when {name}"_sqlp); //as you point outs, "select x"=
=20
> is not sql, we need diffrent postfix.
> tuple(F"{name1}{name2}"); //this is `tuple<const char*, const char*>` or=
=20
> `tuple<const char*, const char*, const char*, const char*, const char*>`?
> tuple(F"{name1} {name2}"); //same type as above?
> translate(F"With {part} to {change}? Can I {change}{order} in any way?",=
=20
> "fr"); //BTW "fr" is part of interpolated string from perspective of this=
=20
> function
> In my case all this things can be enclosed in UDL and will not leak=20
> outside.
>
> Another problem is that even if your version is more flexible you still=
=20
> repeat in multiple of place usage of specialization point functions=20
> otherwise you cant use interpolation without it, in my version you only=
=20
> would need use them in UDL.
>
> Probably without lot of limitation, many quirks will prevent any serous=
=20
> metaprograming. I'm inclined to thinking that whole idea will not go far.
>
> btw
> f(F"T{{a}}"); //is `f("T{{a}}")` or `f("T", {a})`?
> Where both version could compile. Probably safer would be follow JS=20
> version where we it use `${` to start interpolation.
>
>
This could stop Little Bobby Tables:

f(F"{a}{b}");

could translate to

f("", a, "", b, "");


arguments 0, ..., 2n are always literals and 1, ..., 2n-1 are always=20
expressions.

f(F"T{{a}}");

would be=20

f("", {a}, "")


--=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/c753942d-be11-4cc0-bde1-7f71b6184367%40isocpp.or=
g.

------=_Part_12616_1502680122.1518570196678
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, February 13, 2018 at 6:55:47 PM UTC-5, Marcin =
Jaczewski 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"lt=
r"><br><br>On Tuesday, February 13, 2018 at 10:39:35 PM UTC+1, Nicol Bolas =
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">On Tuesday, =
February 13, 2018 at 12:18:59 PM UTC-5, <a>floria...@gmail.com</a> wrote:<b=
lockquote 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 mardi 13 f=C3=A9v=
rier 2018 17:35:49 UTC+1, Nicol Bolas a =C3=A9crit=C2=A0:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div>Because it would never be call=
ed. Basically, what you&#39;d need is this constructor:<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">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">si=
ze_t N</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"><br>string_view</span><span style=3D"color:#660">(</span><span style=3D"=
color:#008">const</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">char</span><span style=3D"color:#000"> s</span><span style=3D"co=
lor:#660">[</span><span style=3D"color:#000">N</span><span style=3D"color:#=
660">]);</span></div></code></div><br>But you already have this constructor=
:<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:#000">string_view</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#008">const</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">char</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">*</span><span style=3D"color:#000">s</span><span style=3D"c=
olor:#660">);</span></div></code></div><br>An array decays into a pointer. =
And since the pointer constructor is not a template, it is considered a bet=
ter match than the array version. And therefore, any ltieral you pass will =
go through the pointer version rather than the array template.<br><br>And i=
t should be noted that this has nothing to do with being a literal. If you =
used a `const char[]` variable, it <i>still</i> would prefer the pointer ve=
rsion due to array-&gt;pointer conversion. So this is not a case of &quot;s=
tring literals are broken now&quot;.<br></div></div></blockquote><div><br><=
/div><div>How can you say that preferring a lossy conversion over a lossles=
s one is not broken? (Here, we lose the length information)<br></div></div>=
</blockquote><div><br>Because the &quot;lossy conversion&quot; part being p=
referred has nothing to do with them being string literals. The lossy conve=
rsion is not the literal-to-array conversion; it&#39;s the array-to-pointer=
 conversion.<br><br>You&#39;re complaining about the wrong problem.<br><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></div><=
div>This make it impossible to work with string literal because they simply=
 don&#39;t exist in the language. This is why I said string literals are br=
oken.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>But there&#39;s no &quot;fix&quot; for this, since any array=
-&gt;pointer &quot;fix&quot; would be both wildly incompatible with C and b=
reak tons and tons of code. So you can either accept the language and work =
with what we have, or rail against it.<br></div></div></blockquote><div></d=
iv><div><div><br></div>Ok it&#39;s not possible to fix array decay because =
of=20
backward compatibility, but it is still possible to fix string literals=20
if we make them something that is not an array.</div></div></blockquote><di=
v><br>Why would changing the behavior of string literals be any more backwa=
rds compatible than changing the behavior of arrays? There&#39;s lots of co=
de out there that works with C++&#39;s string literal rules. Can you find a=
 way to change those rules without breaking their code?<br><br>Let me give =
you a simple case: `decltype(&quot;a string literal&quot;)` is an array typ=
e. Therefore, any BC change will have to leave it as an array type. So what=
 rules would you change to fix the problem you want fixed without changing =
the result of that `decltype`?<br><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>So I rail against those defects in order to =
be heard, and maybe, at some point, they will be fixed.</div></div></blockq=
uote><div><br>Yeah, that&#39;s not how this works. You can &quot;rail again=
st those defects&quot; all you like, but unless you&#39;re willing to actua=
lly work on it (ie: finding a solution that doesn&#39;t break the world and=
 getting it through the committee), it will not get fixed. Or you manage to=
 convince someone who&#39;s actually willing to put in said work to do so.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
If this is not the place to speak out loud about those defects, then where =
should we go?<br></div><div><br></div><div>But don&#39;t get me wrong, when=
 I code, I work with what I have, and I accept the language as it is.<br></=
div><div>=C2=A0</div><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"lt=
r"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div>It&#39;s funny how the more I dig in C++, the more bulky it appears to=
 be just because of these very small annoyances.<br></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br>It&#39;s =
a 3 step process; let&#39;s not interfere in that.<br>=C2=A0</div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>We could ha=
ve exatcly the situation with string interpolation:</div><div><div style=3D=
"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-sty=
le: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"> std</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">concat</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">F</span><span style=3D"color:#080">&quot;{str1}{s=
tr2}{<wbr>str3}&quot;</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">// would be equivalen=
t to</span><span style=3D"color:#000"><br></span><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"> F</span><span style=3D"color:#080">&=
quot;{str1}{str2}{str3}&quot;</span><span style=3D"color:#000">s</span><spa=
n style=3D"color:#660">;</span><span style=3D"color:#000"><br></span></div>=
</code></div><br>I don&#39;t see why allowing UDL to work like that would d=
ecrease usability as we could always use regular functions.<br></div></div>=
</blockquote><div><br>Because you can&#39;t do this:<br><br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px"><code><div><span style=3D"color:#000">std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">concat</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span =
style=3D"color:#080">&quot;some string {variable} other string&quot;</span>=
<span style=3D"color:#000">sv</span><span style=3D"color:#660">);</span></d=
iv></code></div><br>Under my system, the UDL employed here allows you to de=
cide how to process each of the literal fragments. The UDL applies to the p=
arts of the literal that are actually strings. So `concat` would get `strin=
g_view`s, rather than `const char[X]` parameters.<br><br>Under your system,=
 the processing of the literal fragments is controlled entirely by the syst=
em that computes the aggregation.</div></div></blockquote><div><br></div><d=
iv>Let&#39;s sum up, string literals are broken today. So we should probabl=
y try to solve this big issue before trying to see how we can cripple strin=
g_interpolation in order to fit in current-ish C++.<br></div></div></blockq=
uote><div><br>I fail to see why applying a UDL to the literal fragments rat=
her than the interpolation aggregation operation should be considered &quot=
;crippling&quot; string interpolation.<br><br>Whatever breakage you see in =
literals isn&#39;t standing in the way of string interpolation. It&#39;s ju=
st standing in the way of string interpolation working the way <i>you</i> w=
ant it to.<br></div></div></blockquote><div><br></div><div>Because string i=
nterpolation is dealing with string literals,</div></div></blockquote><div>=
<br>Why does it have to be? If constexpr strings are in the future, it&#39;=
d be really nice if string interpolation were defined in such a way that it=
 could be used on them. Tying interpolation to literals is not forward-thin=
king.<br><br></div><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"=
><div>if those literals are broken (and they are), how can we have a proper=
 string interpolation?</div></div></blockquote><div><br>Because any &quot;b=
rokenness&quot; of string literals has no effect on our ability to use stri=
ng interpolation. If you want sized strings for those string fragments, tha=
t&#39;s what the `sv` suffix is for.<br><br>Literal issues only are a probl=
em for string interpolation because you believe that the suffix ought to be=
 able to define the aggregation operation. If you stop believing that, then=
 all of a sudden, your problem with string literals becomes a non-issue for=
 interpolation.<br><br>It should also be noted that this:<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">templat=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">ty=
pename</span><span style=3D"color:#000"> T</span><span style=3D"color:#660"=
>&gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">void</span><span style=3D"color:#000"> foo</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#008">const</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000=
"> t</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br><br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
80">&quot;an array&quot;</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"><br></span></div></code></div><br>The call to `foo` will=
 deduce `T` to be `char[9]`. So a variadic template function that takes the=
 results of string interpolation will get sized array types, not pointers.<=
br><br>Note that this doesn&#39;t invalidate anything I said. The point of =
doing `F&quot;blah {variable} blah&quot;sv` is not necessarily because you =
need them to keep the size around. Using `string_view` has many other advan=
tages, with its member functions, `operator&lt;&lt;` overloads, and the lik=
e. So wanting to apply `sv` to each of the fragments is a perfectly reasona=
ble operation.<br><br>Also, `string_view` is a lot more convenient to use t=
han an array of characters.<br><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></div><div>You said:</div><blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(20=
4,204,204);padding-left:1ex"><div>The point of that discussion was a commen=
t someone made about doing=20
template metaprogramming on string literals. To do that, you need a way=20
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=20
can perform that kind of synthesis.</div></blockquote><div><br></div><div>U=
DL is the only way to do it only because string literals are broken. If we =
had proper string literals, it should be possible to do it simply with regu=
lar functions.</div></div></blockquote><div><br>No, it would not. Even if a=
 string literal had a non-array type with a stored size, each literal value=
 would still not have its own distinct <i>type</i>. Even if the size is a t=
emplate argument, two literals can store different characters while still h=
aving the same size. And you cannot do type-based metaprogramming without h=
aving a 1:1 mapping between value and type.<br><br>Remember: while UDL&#39;=
s <i>can</i> take strings as a sequence of character template parameters, t=
here&#39;s a good reason why they aren&#39;t <i>required</i> to do so. We d=
on&#39;t want to force that onto everybody, and a non-&quot;broken&quot; st=
ring literal system would not force that on people.<br><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>So even with your appro=
ach, broken string literals are a problem for string interpolation. Just no=
t at the same place.</div><div><br></div><div>I&#39;m not sure if my approa=
ch is the right one (it&#39;s probably not), but most of your arguments sta=
nd only because string literal are broken (otherwise, it would have been si=
mple to do the same with my approach too).</div><div><br></div><div>My poin=
t is: yes your approach makes it easier with current C++, but we shouldn&#3=
9;t go for something that works quite well with current C++, but something =
that will work very well with future C++.</div><div>That&#39;s why I think =
it&#39;s better to first fix string literals. And then have string interpol=
ation right the first time.<br></div><div><br></div><div>And btw, if string=
 literals are fixed, string interpolation could be made a library solution =
only ( with a different but reasonable syntax).</div></div></blockquote><di=
v><br>It&#39;s impossible to do that. String interpolation, at its core, is=
 about taking the contents of a string and applying them in some way to the=
 code <i>around</i> that string. A library solution cannot possibly do that=
..<br><br>Oh sure, a `constexpr` function could do the parsing. But then wha=
t? I&#39;m fairly certain that no static reflection proposal provides a mec=
hanism to turn a string into a reference to a local variable. And even if t=
hey did, the location where you&#39;re doing that conversion wouldn&#39;t h=
ave that variable in scope (since it&#39;s in a function call), so it could=
n&#39;t possibly work.<br><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></div><div>PS: I think it would be preferable to sto=
p the discussion here, as it becomes more and more off-topic.<br></div></di=
v></blockquote><div><br>But what if we don&#39;t agree that string interpol=
ation needs better literals?<br><br>Your premise is essentially that my sug=
gested syntax is some kind of compromise, that if literals weren&#39;t &quo=
t;broken&quot; the way you feel that they are, then it would <i>clearly</i>=
 be correct to have UDLs applied to aggregation rather than to the individu=
al fragments.<br><br>I don&#39;t agree with that premise. Whether literals =
are good or broken is a side issue. Even if we had perfect literals, I woul=
d <i>still</i> rather UDLs be focused on individual string literal manipula=
tion rather than string interpolation aggregation.<br></div></div></blockqu=
ote><div>=C2=A0<br><br>After some toughs I come to conclusion that mixing i=
nterpolation with UDL is limiting thing and this is good thing. Why? Becaus=
e beside good things it limit bad things too.<br>I start from high metaprog=
raming starting point where I made all trader offs to make it work, you sta=
rt from basic usage and use opposite options.<br>As consequence all my exam=
ple of use of string interpolation become unusable in your approach.<br><br=
>We can start with sql, you suggest that version:<br><div style=3D"backgrou=
nd-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;=
border-width:1px"><code><div><span style=3D"color:#000">db</span><span styl=
e=3D"color:#660">.</span><span style=3D"color:#008">exec</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D"c=
olor:#080">&quot;some sql stuff {var1} more sql {var2};&quot;</span><span s=
tyle=3D"color:#660">);</span></div></code></div><br>I can quote someone: &q=
uot;Have we learned nothing from Little Bobby Tables?&quot;, how you want d=
isquisition between `const char*`s parameters?<br>I did not had this proble=
m because I can limit how parameters are pass to UDL and I can relay on it.=
<br>One way to avoid it is add new literal that will help with that but in =
some corner cases it could still break.<br><br><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#000">db</span><span style=3D"c=
olor:#660">.</span><span style=3D"color:#008">exec</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#080">&quot;select sth&quot;</span><s=
pan style=3D"color:#000">_sql</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br>db</span><span style=3D"color:#660">.</span><sp=
an style=3D"color:#008">exec</span><span style=3D"color:#660">(</span><span=
 style=3D"color:#000">F</span><span style=3D"color:#080">&quot;select sth w=
hen {name}&quot;</span><span style=3D"color:#000">_sqlp</span><span style=
=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#800">//as you point outs, &quot;select x&quot; is not sql, we need d=
iffrent postfix.</span><span style=3D"color:#000"><br>tuple</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">F</span><span style=3D=
"color:#080">&quot;{name1}{name2}&quot;</span><span style=3D"color:#660">);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//this=
 is `tuple&lt;const char*, const char*&gt;` or `tuple&lt;const char*, const=
 char*, const char*, const char*, const char*&gt;`?</span><span style=3D"co=
lor:#000"><br>tuple</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">F</span><span style=3D"color:#080">&quot;{name1} {name2}&quot;=
</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#800">//same type as above?</span><span style=3D"co=
lor:#000"><br>translate</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">F</span><span style=3D"color:#080">&quot;With {part} to {c=
hange}? Can I {change}{order} in any way?&quot;</span><span style=3D"color:=
#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080"=
>&quot;fr&quot;</span><span style=3D"color:#660">);</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#800">//BTW &quot;fr&quot; is part o=
f interpolated string from perspective of this function</span><span style=
=3D"color:#000"><br></span></div></code></div>In my case all this things ca=
n be enclosed in UDL and will not leak outside.<br><br>Another problem is t=
hat even if your version is more flexible you still repeat in multiple of p=
lace usage of specialization point functions otherwise you cant use interpo=
lation without it, in my version you only would need use them in UDL.<br><b=
r>Probably without lot of limitation, many quirks will prevent any serous m=
etaprograming. I&#39;m inclined to thinking that whole idea will not go far=
..<br><br>btw<br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span st=
yle=3D"color:#000">f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">F</span><span style=3D"color:#080">&quot;T{{a}}&quot;</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#800">//is `f(&quot;T{{a}}&quot;)` or `f(&quot;T&quot;, {=
a})`?</span><span style=3D"color:#000"><br></span></div></code></div>Where =
both version could compile. Probably safer would be follow JS version where=
 we it use `${` to start interpolation.<br><br></div></div></blockquote><di=
v><br></div><div>This could stop Little Bobby Tables:</div><div><br></div><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wor=
d-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span style=3D"color: #000;" class=3D"styled-by-prettify">f</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">&quot;{a}{b}&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><div><br><=
/div><div>could translate to</div><div><br></div><div class=3D"prettyprint"=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"s=
tyled-by-prettify">&quot;&quot;</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;&quot;</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">&quot;&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><div><br><br></div><d=
iv>arguments 0, ..., 2n are always literals and 1, ..., 2n-1 are always exp=
ressions.</div><div><br></div><div><div class=3D"prettyprint" style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">F</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&qu=
ot;T{{a}}&quot;</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span></div></code></div><span style=3D"font-family: monospace; bac=
kground-color: rgb(250, 250, 250); color: rgb(102, 102, 0);"><br></span></d=
iv><div>would be=C2=A0</div><div><br></div><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
 border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;=
" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;&quot;</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">},</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&quot;&quot;</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br></di=
v><div><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/c753942d-be11-4cc0-bde1-7f71b6184367%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c753942d-be11-4cc0-bde1-7f71b6184367=
%40isocpp.org</a>.<br />

------=_Part_12616_1502680122.1518570196678--

------=_Part_12615_215957504.1518570196677--

.
