Topic: [Draft] Unform move and forward


Author: mihailnajdenov@gmail.com
Date: Thu, 7 Jun 2018 11:44:56 -0700 (PDT)
Raw View
------=_Part_56170_1687013032.1528397096470
Content-Type: multipart/alternative;
 boundary="----=_Part_56171_1432040016.1528397096470"

------=_Part_56171_1432040016.1528397096470
Content-Type: text/plain; charset="UTF-8"

This is continuation of a previous topic
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>


Hello, I have written a proposal for merging `forward` and `move` behind a
new postscript operator &&>

This is the initial draft. Feedback is welcome.

Thank You
MihailNaydenov

--
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/eb24413b-3aa0-48e3-ad06-f77e949a498e%40isocpp.org.

------=_Part_56171_1432040016.1528397096470
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>This is continuation of a <a href=3D"https://groups.g=
oogle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ">previo=
us topic</a>=C2=A0</div><div><br></div><div>Hello, I have written a proposa=
l for merging `forward` and `move` behind a new postscript operator &amp;&a=
mp;&gt;</div><div><br></div><div>This is the initial draft. Feedback is wel=
come.</div><div><br></div><div>Thank You<br></div><div>MihailNaydenov=C2=A0=
</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/eb24413b-3aa0-48e3-ad06-f77e949a498e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/eb24413b-3aa0-48e3-ad06-f77e949a498e=
%40isocpp.org</a>.<br />

------=_Part_56171_1432040016.1528397096470--

------=_Part_56170_1687013032.1528397096470
Content-Type: text/html; charset=UTF-8; name=uniform-move-and-forward.html
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=uniform-move-and-forward.html
X-Attachment-Id: 61f05741-5eb9-4d07-9bfe-0e2af755328b
Content-ID: <61f05741-5eb9-4d07-9bfe-0e2af755328b>

=EF=BB=BF<!DOCTYPE html>
<html>

<head>
  <meta charset=3D"utf-8">
  <meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=3D=
1.0">
  <title>uniform</title>
  <link rel=3D"stylesheet" href=3D"https://stackedit.io/style.css" />
</head>

<body class=3D"stackedit">
  <div class=3D"stackedit__html"><p>Document number: xxx<br>
Date: 2018-7-06<br>
Audience: EWG<br>
Reply-To: Mihail Naydenov &lt;mihailnajdenov at gmail dot com&gt;</p>
<hr>
<h1 align=3D"center">Uniform 'move' and 'forward' syntax</h1>
<h2 id=3D"intro">Intro</h2>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">auto</span> cally <span class=3D"token operator">=3D</s=
pan> <span class=3D"token punctuation">[</span><span class=3D"token punctua=
tion">]</span><span class=3D"token punctuation">(</span><span class=3D"toke=
n keyword">auto</span><span class=3D"token operator">&amp;&amp;</span> func=
<span class=3D"token punctuation">,</span> <span class=3D"token keyword">au=
to</span><span class=3D"token operator">&amp;&amp;</span><span class=3D"tok=
en punctuation">.</span><span class=3D"token punctuation">.</span><span cla=
ss=3D"token punctuation">.</span> y<span class=3D"token punctuation">)</spa=
n> =20
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">return</span> func<span class=3D"token oper=
ator">&amp;&amp;</span><span class=3D"token operator">&gt;</span><span clas=
s=3D"token punctuation">(</span>args<span class=3D"token operator">&amp;&am=
p;</span><span class=3D"token operator">&gt;</span><span class=3D"token pun=
ctuation">.</span><span class=3D"token punctuation">.</span><span class=3D"=
token punctuation">.</span><span class=3D"token punctuation">)</span><span =
class=3D"token punctuation">;</span> <span class=3D"token comment">//&lt; f=
orward without extreme verbosity</span>
<span class=3D"token punctuation">}</span>
</code></pre>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp">Class<span=
 class=3D"token operator">::</span><span class=3D"token function">Class</sp=
an><span class=3D"token punctuation">(</span>string<span class=3D"token ope=
rator">&amp;&amp;</span> name<span class=3D"token punctuation">,</span> fun=
ction<span class=3D"token operator">&amp;&amp;</span> func<span class=3D"to=
ken punctuation">)</span>
<span class=3D"token operator">:</span> <span class=3D"token function">_nam=
e</span><span class=3D"token punctuation">(</span>name<span class=3D"token =
operator">&amp;&amp;</span><span class=3D"token operator">&gt;</span><span =
class=3D"token punctuation">)</span><span class=3D"token punctuation">,</sp=
an> <span class=3D"token function">_func</span><span class=3D"token punctua=
tion">(</span>func<span class=3D"token operator">&amp;&amp;</span><span cla=
ss=3D"token operator">&gt;</span><span class=3D"token punctuation">)</span>=
 <span class=3D"token comment">//&lt; move with natural syntax</span>
<span class=3D"token punctuation">{</span><span class=3D"token punctuation"=
>}</span>
</code></pre>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">decltype</span><span class=3D"token punctuation">(</spa=
n><span class=3D"token keyword">auto</span><span class=3D"token punctuation=
">)</span> <span class=3D"token function">insert</span><span class=3D"token=
 punctuation">(</span>string<span class=3D"token operator">&amp;&amp;</span=
> name<span class=3D"token punctuation">,</span> <span class=3D"token keywo=
rd">auto</span><span class=3D"token operator">&amp;&amp;</span> func<span c=
lass=3D"token punctuation">)</span> =20
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">return</span> acts<span class=3D"token punc=
tuation">.</span><span class=3D"token function">emplace</span><span class=
=3D"token punctuation">(</span>name<span class=3D"token operator">&amp;&amp=
;</span><span class=3D"token operator">&gt;</span><span class=3D"token punc=
tuation">,</span> func<span class=3D"token operator">&amp;&amp;</span><span=
 class=3D"token operator">&gt;</span><span class=3D"token punctuation">)</s=
pan><span class=3D"token punctuation">;</span> <span class=3D"token comment=
">//&lt; no uncertainty when to use each one</span>
<span class=3D"token punctuation">}</span>
</code></pre>
<p>This proposal introduces a dedicated postscript operator, which handles =
<code>std::forward</code> and <code>std::move</code> in a unified fashion, =
behind a single, simple, terse syntax.</p>
<h2 id=3D"motivation">Motivation</h2>
<h3 id=3D"motivation-for-uniformity">Motivation for uniformity</h3>
<p>In the decade of use of <code>move</code> and <code>forward</code> three=
 observation can be made:</p>
<ul>
<li>One uses <em>either</em> <code>move</code> <em>or</em> <code>forward</c=
ode>;</li>
<li>It is always clear when to use what, using one in the place of the othe=
r is <em>in practice</em> always wrong;</li>
<li>The results of the operations are <em>effectively</em> the same - objec=
t if passed along and its identifier should not be further used as it is;</=
li>
</ul>
<p>The first two observations lead to the conclusion, usage of the two func=
tions is <em>statically deterministic</em> and not bound to a decision maki=
ng.<br>
The third observation tell us, there is <em>underlying concept</em>, connec=
ting both operations to a common base - the concept of passing-along and gi=
ving up usage rights over an object.</p>
<p>This all lead us to believe, it is possible to come up with a more gener=
al operation, which combines the currently used two separate operations. Do=
ing so will have multiple positive benefits:</p>
<ul>
<li><strong>Less fragile code</strong></li>
</ul>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">template</span><span class=3D"token operator">&lt;</spa=
n><span class=3D"token keyword">class</span> <span class=3D"token class-nam=
e">F</span><span class=3D"token operator">&gt;</span>
<span class=3D"token keyword">decltype</span><span class=3D"token punctuati=
on">(</span><span class=3D"token keyword">auto</span><span class=3D"token p=
unctuation">)</span> <span class=3D"token function">insert</span><span clas=
s=3D"token punctuation">(</span>string<span class=3D"token operator">&amp;&=
amp;</span> name<span class=3D"token punctuation">,</span> F<span class=3D"=
token operator">&amp;&amp;</span> func<span class=3D"token punctuation">)</=
span> =20
<span class=3D"token punctuation">{</span>
 <span class=3D"token keyword">return</span> actions<span class=3D"token pu=
nctuation">.</span><span class=3D"token function">emplace</span><span class=
=3D"token punctuation">(</span>std<span class=3D"token operator">::</span><=
span class=3D"token function">move</span><span class=3D"token punctuation">=
(</span>name<span class=3D"token punctuation">)</span><span class=3D"token =
punctuation">,</span> std<span class=3D"token operator">::</span>forward<sp=
an class=3D"token operator">&lt;</span>F<span class=3D"token operator">&gt;=
</span><span class=3D"token punctuation">(</span>func<span class=3D"token p=
unctuation">)</span><span class=3D"token punctuation">)</span><span class=
=3D"token punctuation">;</span>=20
<span class=3D"token punctuation">}</span>
</code></pre>
<p>In the above example, if the user decides to =E2=80=9Cupgrade=E2=80=9D t=
he function to make the <code>name</code> argument a templated one, he <em>=
must</em> remember to also change <code>move</code> to <code>forward</code>=
 or risk either confusion for the people reading the code or unexpected beh=
avior.</p>
<p>With the current proposal the user (or tools), can change the function s=
ignature and the code will still behave correctly in de-facto all cases.</p=
>
<ul>
<li>
<p><strong>One less thing to learn and remember</strong><br>
The distinction b/w <code>forward</code> and <code>move</code> is subtle, a=
rguably it is an =E2=80=9Cadvanced understanding=E2=80=9D. However, this un=
derstanding does not contribute to writing better code.<br>
The tools to write better code are =E2=80=9Cforwarding references=E2=80=9D =
and =E2=80=9Crvalue references=E2=80=9D, and not the fact a separate functi=
on is needed to use each feature.<br>
In other words, right now one must learn three topics:</p>
<ul>
<li>Forwarding references;</li>
<li>Rvalue references and move constructors;</li>
<li>Learn about <code>move</code> and <code>forward</code>, when to use the=
m and when <em>not</em> to use them;</li>
</ul>
<p>From the above three, only the first two are <em>fundamental concepts</e=
m> of the language.<br>
The last one are <em>helper constructs</em>.</p>
</li>
</ul>
<p>With the current proposal focus is left on the fundamental features and =
<em>away</em> from the helper tools. These tools are brought to the absolut=
e minimum <em>both</em> semantically <em>and</em> syntactically.</p>
<ul>
<li><strong>The compiler should be the one writing boilerplate code</strong=
><br>
Considering that, on one hand, there is no decision making of when to use <=
code>move</code> and when <code>forward</code> - this is always predetermin=
ed - and, on the other, the compiler has all the necessary information to d=
o the right choice, there is very little gain of not letting it do the job =
for us.</li>
</ul>
<p>This proposal considers <code>move</code> and <code>forward</code> boile=
rplate (helper tools), which should be streamlined by the compiler as much =
as possible.</p>
<ul>
<li><strong>Higher level abstractions are better, if the lower ones do not =
grant us more possibilities</strong><br>
Lets consider a higher abstraction function in the form of a destructor or =
a <code>dispose()</code> method, against specific implementations in the fo=
rm of some hypothetical <code>image.freeData()</code> or <code>file.close()=
</code>. In almost all, if not all cases the destructor or <code>dispose()<=
/code> is the better interface because, beyond explicitness, one gains noth=
ing from using the specific methods and lose much more in the form of less =
generic code.</li>
</ul>
<p>This proposal argues the case here is analogous - use of specific implem=
entations, in the form of <code>forward</code> and <code>move</code>, is in=
ferior to the use of the higher concept of =E2=80=9Cobject passing=E2=80=9D=
..</p>
<ul>
<li><strong>Any good operator for <code>move</code> is also good one for <c=
ode>forward</code></strong><br>
This might look like a cop out, but in reality if a good operator is found =
for one of the functions it will either be also equally useful for the othe=
r, or it will be <em>very</em> hard to come up with similar one for the oth=
er function as well. This goes the opposite direction as well - as long as =
we are not forced to came up with a <em>specific</em> operator, it will be =
easier to actually came up with one.</li>
</ul>
<p>This proposal recognizes strong connection b/w <code>move</code> and <co=
de>forward</code> and considers a single operator the best solution.</p>
<h3 id=3D"motivation-for-use-of-an-operator">Motivation for use of an opera=
tor</h3>
<p>There are multiple good reasons to consider an operator something of hig=
h value:</p>
<ol>
<li>Both <code>move</code> and <code>forward</code> are interfaces to <em>f=
undamental, wildly used</em> language constructs. They should be represente=
d by language-level syntax. Right now, the much less common operation to ta=
ke the address of an object has a language level construct, and the much mo=
re commonly used one - to pass an object - does not. There is a strong cont=
rast with the fact the entire machinery for <code>move</code> and <code>for=
ward</code> is language based - move ctors, special decorator, reference co=
llapsing - yet there no language construct to use them.</li>
<li>Currently we need to explain that =E2=80=9Cmove does not actually move=
=E2=80=9D and that =E2=80=9Cmove and forward are just a cast=E2=80=9D. This=
 is because <code>move</code> and <code>forward</code> present themselves a=
s a function similar to other <code>std</code> functions like <code>std::co=
py</code> and <code>std::ref</code>, which, like most functions, <em>do</em=
> perform a =E2=80=9Creal work=E2=80=9D. Casts on the other hand are langua=
ge level, <code>constexpr</code> for the most part, actions, performing ess=
entially compiler directives, not =E2=80=9Creal work=E2=80=9D. Operators fi=
t that purpose best.</li>
<li>An operator has the least amount of verbosity, which is welcome for bot=
h <code>move</code> and <code>forward</code> as in both cases the operation=
 is already part of some bigger expression -<br>
<code>func(std::forward&lt;A&gt;(a), std::forward&lt;B&gt;(b))</code>, <cod=
e>_member{std::move(val)}</code>, <code>std::move(val).call()</code>.</li>
</ol>
<h3 id=3D"motivation-against-the-use-of-a-keyword">Motivation against the u=
se of a keyword</h3>
<p>Using a keyword in this particular case will have few disadvantages.</p>
<p>First,  it will not be short and terse enough to be attractive alternati=
ve to current functions, especially to <code>move</code>.</p>
<p>Second and more importantly, inviting a keyword for both <code>move</cod=
e> and <code>forward</code> will have the unwanted side effect of introduci=
ng a new term, a new category to learn and articulate. Instead of just talk=
ing about =E2=80=9Cforwarding references=E2=80=9D and rvalue references and=
 the syntax to use these, we will have to talk about object <code>give</cod=
e>ing or <code>pass</code>ing as some sort of separate category. Keywords, =
even more then functions, make things way too =E2=80=9Cofficial=E2=80=9D an=
d declarative, where operators are <em>just syntax</em> - we don=E2=80=99t =
name what we don=E2=80=99t have to name. Where with <code>new</code> and <c=
ode>make_</code> for example naming the action is beneficial, here naming t=
he action like <code>give</code> or <code>pass</code>  is overly formal and=
, as said, creates an extra unneeded term.</p>
<p>Last, but not least, introducing a new keyword to C++ has proven to be v=
ery difficult task and the results are filled with compromises.</p>
<h3 id=3D"motivation-regarding-stdmove">Motivation regarding std::move</h3>
<p><code>move</code> on its own, as a function (or keyword for that matter)=
, can be misleading.</p>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">void</span> <span class=3D"token function">f</span><spa=
n class=3D"token punctuation">(</span><span class=3D"token punctuation">)</=
span>
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">const</span> <span class=3D"token keyword">=
auto</span> obj <span class=3D"token operator">=3D</span> <span class=3D"to=
ken function">get_object</span><span class=3D"token punctuation">(</span><s=
pan class=3D"token punctuation">)</span><span class=3D"token punctuation">;=
</span>
  <span class=3D"token function">func</span><span class=3D"token punctuatio=
n">(</span>std<span class=3D"token operator">::</span><span class=3D"token =
function">move</span><span class=3D"token punctuation">(</span>obj<span cla=
ss=3D"token punctuation">)</span><span class=3D"token punctuation">)</span>=
<span class=3D"token punctuation">;</span> =20
<span class=3D"token punctuation">}</span>
</code></pre>
<p>This code is valid, but misleading and probably even worrisome to a juni=
or developer. The reason for this is the fact we advertise <code>move</code=
> as =E2=80=9Ca cast=E2=80=9D at which point an unexperienced user might th=
ink, <code>move</code> is able to cast away <code>const</code> and still mo=
ve the object, which is wrong.<br>
Another, even simpler example <code>int a =3D 5; int b =3D std::move(a);</c=
ode><br>
A junior developer will ask - =E2=80=9CWhat happens to <code>a</code>, what=
 value does it have, it is 0, is it =E2=80=98empty=E2=80=99?=E2=80=9D These=
 are not stupid and unreasonable questions.</p>
<p>The reality of the matter is, <code>move</code> might or not move. Being=
 =E2=80=9Cexplicit=E2=80=9D about it does not make it do what it is not sup=
posed to, or able to, do, but this can lead to a confusion.</p>
<p>On the other hand if we advertise the action as simply =E2=80=9Cobject p=
assing=E2=80=9D, the contradiction disappears, because passing by implicit =
copy (iff moving is not possible) is also perfectly valid semantically and =
we no longer =E2=80=9Clie=E2=80=9D in code.<br>
The last argument might seem better served by a keyword, but as argued alre=
ady, the price of introducing a new keyword is not worth the outcome. Using=
 an operator enables the action to be a general expression, not bound to an=
y spelled-out, potentially incorrect or overly formal statements.</p>
<h3 id=3D"motivation-regarding-stdforward">Motivation regarding std::forwar=
d</h3>
<p><code>forward</code> is arguably even more problematic and has been alre=
ady a target for debate and previous proposals<sup class=3D"footnote-ref"><=
a id=3D"fnref1" href=3D"#fn1">1</a></sup>.<br>
For completeness I will list the problems again here:</p>
<ul>
<li>Subtle difference with <code>move</code> which leads to uncertainly in =
novice programmers.</li>
<li>The function is used only in one context and that context alone - to pa=
ss-on a =E2=80=9Cforwarding reference=E2=80=9D. This can be seen as quite o=
dd for a function with such a broad name.</li>
<li>Mandatory template argument is unexpected to novice programmers, especi=
ally if they are introduced to <code>move</code> around the same time, whic=
h is it is often the case.  Mandatory explicit template arguments in genera=
l are not common and in some situations are even considered an anti-pattern=
..</li>
<li>The template argument itself can be confusing for what works and what d=
oes not - what are the dos and don=E2=80=99ts. Should/could, for instance, =
decorations be used? Should/could a different type be specified?</li>
<li>For professionals the main issue is the verbosity of both the function =
itself - as it appears in the very verbose context of templates - and, in t=
he case of generic lambda, the template argument itself.  This issue is exp=
lored in detail in P0644<sup class=3D"footnote-ref"><a id=3D"fnref1:1" href=
=3D"#fn1">1</a></sup></li>
</ul>
<h2 id=3D"design-decisions">Design Decisions</h2>
<h3 id=3D"postscript-operator-">Postscript operator &amp;&amp;&gt;</h3>
<p>This proposal considers best solution to all requirements the introducti=
on of a postscript operator <code>&amp;&amp;&gt;</code> with the following =
behavior.</p>
<ul>
<li>The expression <code>val&amp;&amp;&gt;</code> is semantically equivalen=
t to <code>std::forward&lt;decltype(val)&gt;(val)</code>, iff <code>val</co=
de> is an identifier for a =E2=80=9Cforwarding reference=E2=80=9D.</li>
<li>In all other cases the expression <code>val&amp;&amp;&gt;</code> is sem=
antically equivalent to <code>std::move(val)</code>.</li>
</ul>
<p>The syntax is specifically chosen to serve a purpose - it is visually re=
miniscent of both rvalue reverences (<code>std::string&amp;&amp;</code>) an=
d =E2=80=9Cforwarding references=E2=80=9D <code>T&amp;&amp;</code>, <code>a=
uto&amp;&amp;</code>.<br>
It also has an angle bracket <code>&gt;</code>, used to visually signal mov=
ement (moving/forwarding), but most importandly, to syntactically disambigu=
ate against the existing operator &amp;&amp;:<br>
<code>a &amp;&amp; (b || c); //&lt; operator&amp;&amp;(a, operator||(b, c))=
</code><br>
<code>a&amp;&amp;&gt;(b || c); //&lt; std::move(a)(operator||(b, c))</code>=
</p>
<p>Being postfix is also of importance because this enables syntax options,=
 impossible otherwise. For instance it would have been much harder to use t=
he ampersand <code>&amp;</code> as it is already an existing prefix operato=
r.<br>
It also makes the code readable in a natural left to right way:<br>
<code>img&amp;&amp;&gt;.mirrored(); // varibale 'img', convert to rvalue, c=
all mirrored() &amp;&amp;</code><br>
<code>func(arg&amp;&amp;&gt;); // call 'func' with argument 'arg', converte=
d back to "forwarding reference"</code></p>
<h4 id=3D"can-operator--be-a-normal-operator-function">Can operator &amp;&a=
mp;&gt; be a normal operator function?</h4>
<p>No. <code>move</code> can be an operator function, but <code>forward</co=
de> needs a type argument, making it unsuitable.<br>
In the later case, this proposal envisions the compiler supplying the neede=
d template argument =E2=80=9Cbehind the scenes=E2=80=9D.</p>
<h4 id=3D"can-operator--be-implemented-in-terms-of-overloading-or-enable_if=
">Can operator &amp;&amp;&gt; be implemented in terms of overloading or <co=
de>enable_if</code>?</h4>
<p>No. Currently there is no mechanism to tell if an identifier is a =E2=80=
=9Cforwarding reference=E2=80=9D.<br>
This proposal assumes, however, such a distinction is possible on compiler/=
preprocessor level.</p>
<h3 id=3D"should-stdmove-and-stdforward-be-deprecated">Should std::move and=
 std::forward be deprecated?</h3>
<p>No. This proposal anticipates, <code>move</code> and <code>forward</code=
> to still be used by people who like to be explicit in the syntax, much th=
e same way some people use <code>or</code> and <code>not</code> instead of =
<code>||</code> and <code>!</code>. Also, <code>move</code> and <code>forwa=
rd</code> can be used as teaching tool, to illustrate and explain the proce=
ss of moving and forwarding as well as workings of the proposed operator it=
self. Last, but not least <code>forward</code> can be used to forward an ar=
gument as a different type. Should be noted, that last case is rare and a c=
ast could be a better option so that the action will stand out as unordinar=
y.</p>
<h2 id=3D"previous-work">Previous work</h2>
<p>The author is not aware of previous proposal to merge <code>move</code> =
and <code>forward</code>.<br>
The already mentioned p0644<sup class=3D"footnote-ref"><a id=3D"fnref1:2" h=
ref=3D"#fn1">1</a></sup> deals with the issues regarding <code>forward</cod=
e> and proposes an operator to solve these issues. That proposal was not ac=
cepted, mainly on the grounds of potential confusion to the users<sup class=
=3D"footnote-ref"><a id=3D"fnref2" href=3D"#fn2">2</a></sup>.</p>
<p>Current proposal argues the majority of the issues are alleviated by a p=
ostfix operator, as demonstrated in the previous chapters. The author belie=
ves, not only there is no visual confusion when using the proposed operator=
 &amp;&amp;&gt;, but a strong correlation is build b/w both =E2=80=9Cforwar=
ding references=E2=80=9D and revalue references on one hand, and the syntax=
 to use them on the other.</p>
<h2 id=3D"acknowledgements">Acknowledgements</h2>
<p>Special thanks to Ga=C5=A1per A=C5=BEman, Nicol Bolas, Nicolas Lesser an=
d other Future Proposals group users for early discussions and corrections<=
sup class=3D"footnote-ref"><a id=3D"fnref3" href=3D"#fn3">3</a></sup>.</p>
<hr class=3D"footnotes-sep">
<section class=3D"footnotes">
<ol class=3D"footnotes-list">
<li class=3D"footnote-item" id=3D"fn1"><p><a href=3D"http://open-std.org/JT=
C1/SC22/WG21/docs/papers/2017/p0644r1.html">Forward without =E2=80=98forwar=
d=E2=80=99</a>. <a class=3D"footnote-backref" href=3D"#fnref1">=E2=86=A9=EF=
=B8=8E</a> <a class=3D"footnote-backref" href=3D"#fnref1:1">=E2=86=A9=EF=B8=
=8E</a> <a class=3D"footnote-backref" href=3D"#fnref1:2">=E2=86=A9=EF=B8=8E=
</a></p>
</li>
<li class=3D"footnote-item" id=3D"fn2"><p><a href=3D"https://botondballo.wo=
rdpress.com/2017/11/20/trip-report-c-standards-meeting-in-albuquerque-novem=
ber-2017/">Trip Report: november-2017</a> <a class=3D"footnote-backref" hre=
f=3D"#fnref2">=E2=86=A9=EF=B8=8E</a></p>
</li>
<li class=3D"footnote-item" id=3D"fn3"><p><a href=3D"https://groups.google.=
com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ">C++ Future P=
roposals</a> <a class=3D"footnote-backref" href=3D"#fnref3">=E2=86=A9=EF=B8=
=8E</a></p>
</li>
</ol>
</section>
</div>
</body>

</html>

------=_Part_56170_1687013032.1528397096470--

.


Author: j c <james.a.cooper@gmail.com>
Date: Thu, 7 Jun 2018 23:31:14 +0100
Raw View
--0000000000005b0cad056e14d700
Content-Type: text/plain; charset="UTF-8"

Personally, I think the &&> operator is visually ugly and reminds me of
something Perl would have.

Why not get the compiler to expose the Information it has 'behind the
scenes' so that a std::pass() function can be added that does the right
thing?


On Thursday, June 7, 2018, <mihailnajdenov@gmail.com> wrote:

> This is continuation of a previous topic
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
>
> Hello, I have written a proposal for merging `forward` and `move` behind a
> new postscript operator &&>
>
> This is the initial draft. Feedback is welcome.
>
> Thank You
> MihailNaydenov
>
> --
> 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/eb24413b-3aa0-48e3-
> ad06-f77e949a498e%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/eb24413b-3aa0-48e3-ad06-f77e949a498e%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CAFQaeCCw6RndVrsWEUSN_TxNaw%2B-gKEZ3CXFWNThkfzSD9b01g%40mail.gmail.com.

--0000000000005b0cad056e14d700
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Personally, I think the &amp;&amp;&gt; operator is visually ugly and remind=
s me of something Perl would have.<div><div><br></div><div>Why not get the =
compiler to expose the Information it has &#39;behind the scenes&#39; so th=
at a std::pass() function can be added that does the right thing?</div><div=
><br></div><div><br>On Thursday, June 7, 2018,  &lt;<a href=3D"mailto:mihai=
lnajdenov@gmail.com">mihailnajdenov@gmail.com</a>&gt; wrote:<br><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>This is continuation of a <a href=
=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/=
wXHhTLpbDQAJ" target=3D"_blank">previous topic</a>=C2=A0</div><div><br></di=
v><div>Hello, I have written a proposal for merging `forward` and `move` be=
hind a new postscript operator &amp;&amp;&gt;</div><div><br></div><div>This=
 is the initial draft. Feedback is welcome.</div><div><br></div><div>Thank =
You<br></div><div>MihailNaydenov=C2=A0</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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/eb24413b-3aa0-48e3-ad06-f77e949a498e%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/eb24=
413b-3aa0-48e3-<wbr>ad06-f77e949a498e%40isocpp.org</a><wbr>.<br>
</blockquote></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/CAFQaeCCw6RndVrsWEUSN_TxNaw%2B-gKEZ3C=
XFWNThkfzSD9b01g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFQaeCCw6RndVr=
sWEUSN_TxNaw%2B-gKEZ3CXFWNThkfzSD9b01g%40mail.gmail.com</a>.<br />

--0000000000005b0cad056e14d700--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Fri, 8 Jun 2018 03:00:59 +0300
Raw View
On 06/08/18 01:31, j c wrote:
> Personally, I think the &&> operator is visually ugly and reminds me of
> something Perl would have.

+1. As some people say, Perl is a language one writes in, but never
reads afterwards. :) Let's not make C++ fit these words as well.

> Why not get the compiler to expose the Information it has 'behind the
> scenes' so that a std::pass() function can be added that does the right
> thing?

I'm not really convinced that unifying std::move and std::forward would
result in a better code. Those operations are not equivalent, even if
the effect is similar. In my code I would still prefer std::move or
std::forward instead of the unified construct.

What could be improved though is to allow the template argument of
std::forward to be omitted.

--
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/c98d8b52-4f53-bd61-818b-dcb9908f3292%40gmail.com.

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Fri, 8 Jun 2018 03:32:28 +0300
Raw View
On 06/07/18 21:44, mihailnajdenov@gmail.com wrote:
> This is continuation of a previous topic
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
>
> Hello, I have written a proposal for merging `forward` and `move` behind
> a new postscript operator &&>
>
> This is the initial draft. Feedback is welcome.

I disagree with the motivation you presented, in particular, this point:

  - It is always clear when to use what, using one in the place of the
other is in practice always wrong;

While it is likely clear to the developer which construct to use, this
knowledge does not follow from the code so that it can be inferred by
the compiler. The choice of the construct is made by the developer,
depending on what he wants to do. For example:


   template< typename T >
   void foo(T&& value)
   {
     vec.push_back(std::pass(value));
   }

   std::string str;
   foo(str);

It is not clear what this code intends to do. If std::pass acts
similarly to to std::forward then str is left intact and can be used
later. If it is equivalent to std::move then str is empty afterwards.
Both interpretations are reasonable and I've seen code written both ways
in different cases.

Forwarding and moving a value have a fundamental difference in strength.
Forwarding does not move the value unless permitted by the program (i.e.
the value is assumed to be unused afterwards) while std::move is
stronger and will move even lvalue. The fact that both may end up moving
the value does not mean they are the same and should be expressed the
same way. Being more explicit about the intent is beneficial to the
developer, experienced or junior.

--
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/1553e65a-b167-2e5e-cfc5-7839b4720eb6%40gmail.com.

.


Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Fri, 8 Jun 2018 03:48:40 +0100
Raw View
--000000000000925dc5056e18703e
Content-Type: text/plain; charset="UTF-8"

I was initially sceptical about the syntax. A part of me still is. However,
you have explained it well and I think it will become more visually
appealing the more we use it. I can't think of a better alternative.

As for the rest of the proposal, I think your motivation is good enough.
When I first came across move and forward it felt like trying to navigate a
conceptual minefield. Syntax like this makes the whole topic easier on
beginners, and that's fantastic.

In terms of the proposal writeup, my main criticism is that parts of it is
written in a slightly defensive manner, and this might be a disadvantage.
Does anyone else get the same vibe, or is it just me? There are also a
couple of grammatical slips, but that is a later concern.

The main part is in convincing people that this is a beneficial and
worthwhile change - from reading this draft alone, I went from thinking it
was ugly and pointless, to thinking that it's a good choice of syntax for a
good choice of functionality. So as far as I'm concerned, that's a thumbs
up.

>

--
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/CAC%2B0CCNZMuxtkxbpO%3DwNyPK%3D-V2o32k%3DFBFCFtRGSE%3DhxVjaYQ%40mail.gmail.com.

--000000000000925dc5056e18703e
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div class=3D"gmail_quote" dir=3D"auto"><div dir=3D"ltr">=
I was initially sceptical about the syntax. A part of me still is. However,=
 you have explained it well and I think it will become more visually appeal=
ing the more we use it. I can&#39;t think of a better alternative.<br></div=
></div><div dir=3D"auto"><br></div><div dir=3D"auto">As for the rest of the=
 proposal, I think your motivation is good enough. When I first came across=
 move and forward it felt like trying to navigate a conceptual minefield. S=
yntax like this makes the whole topic easier on beginners, and that&#39;s f=
antastic.</div><div dir=3D"auto"><br></div><div dir=3D"auto">In terms of th=
e proposal writeup, my main criticism is that parts of it is written in a s=
lightly defensive manner, and this might be a disadvantage. Does anyone els=
e get the same vibe, or is it just me? There are also a couple of grammatic=
al slips, but that is a later concern.</div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">The main part is in convincing people that this is a benefic=
ial and worthwhile change - from reading this draft alone, I went from thin=
king it was ugly and pointless, to thinking that it&#39;s a good choice of =
syntax for a good choice of functionality. So as far as I&#39;m concerned, =
that&#39;s a thumbs up.</div><div class=3D"gmail_quote" dir=3D"auto"><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
 solid;padding-left:1ex">
</blockquote></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/CAC%2B0CCNZMuxtkxbpO%3DwNyPK%3D-V2o32=
k%3DFBFCFtRGSE%3DhxVjaYQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0=
CCNZMuxtkxbpO%3DwNyPK%3D-V2o32k%3DFBFCFtRGSE%3DhxVjaYQ%40mail.gmail.com</a>=
..<br />

--000000000000925dc5056e18703e--

.


Author: mihailnajdenov@gmail.com
Date: Thu, 7 Jun 2018 23:32:03 -0700 (PDT)
Raw View
------=_Part_46724_986399039.1528439523681
Content-Type: multipart/alternative;
 boundary="----=_Part_46725_356614721.1528439523681"

------=_Part_46725_356614721.1528439523681
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 3:32:32 AM UTC+3, Andrey Semashev wrote:
>
> On 06/07/18 21:44, mihailn...@gmail.com <javascript:> wrote:
> > This is continuation of a previous topic
> > <
> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
> >
> >
> > Hello, I have written a proposal for merging `forward` and `move` behind
> > a new postscript operator &&>
> >
> > This is the initial draft. Feedback is welcome.
>
> I disagree with the motivation you presented, in particular, this point:
>
>   - It is always clear when to use what, using one in the place of the
> other is in practice always wrong;
>
> While it is likely clear to the developer which construct to use, this
> knowledge does not follow from the code so that it can be inferred by
> the compiler. The choice of the construct is made by the developer,
> depending on what he wants to do. For example:
>
>
>    template< typename T >
>    void foo(T&& value)
>    {
>      vec.push_back(std::pass(value));
>    }
>
>    std::string str;
>    foo(str);
>
> It is not clear what this code intends to do. If std::pass acts
> similarly to to std::forward then str is left intact and can be used
> later. If it is equivalent to std::move then str is empty afterwards.


Why should there be an "if"? The signature of the function is T&& from that
alone follows 'value' is forwarded.

If one writes a function where he moves instead of forwarding


   template< typename T >
   void foo(T&& value)
   {
     vec.push_back(std::move(value));
   }

That will be *The Wrong Thing* to do.

This is because one *lies against the interface *- T&& is a forwarding
reference,* by definition*.

Using "object passing", *prevents* you to lie!


See a similar post from the original discussion for detailed explanation
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ


>
> Both interpretations are reasonable and I've seen code written both ways
> in different cases.


> Forwarding and moving a value have a fundamental difference in strength.
> Forwarding does not move the value unless permitted by the program (i.e.
> the value is assumed to be unused afterwards) while std::move is
> stronger and will move even lvalue. The fact that both may end up moving
> the value does not mean they are the same and should be expressed the
> same way. Being more explicit about the intent is beneficial to the
> developer, experienced or junior.
>

Question is what is the original intend? And actually the intend in both
cases is to give the object away.
This is what the user wants - nothing more nothing less.
What are the object characteristics before giving it up and in what form
the give operation takes pace, is of no interest.



About the "ugliness".

Well, I really hoped a simple && would do the trick, but it does clash with
the binary operator && and I see no way around that.

An alternative might be val~~ or val~&& or just val~ or a keyword val
passin.

See the massive study done in the original post about an operator
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/PNyDb_UEAAAJ>and
about a keyword
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/r0o4Wy04AQAJ>

Of course suggestions are welcome.

--
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/cdb56799-3625-42d5-bbca-2af5fd525eb9%40isocpp.org.

------=_Part_46725_356614721.1528439523681
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 3:32:32 AM UTC+3, Andre=
y Semashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 06/07/18 2=
1:44, <a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onc=
lick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascript:=
" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"bmdZ0b4ABQAJ"=
>mihailn...@gmail.com</a> wrote:
<br>&gt; This is continuation of a previous topic=20
<br>&gt; &lt;<a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a=
/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;"=
 onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/s=
td-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;" href=3D"https://gr=
oups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" =
target=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.=
org/d/msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>wXHhTLpbDQAJ</a>&gt;=20
<br>&gt;=20
<br>&gt;=20
<br>&gt; Hello, I have written a proposal for merging `forward` and `move` =
behind=20
<br>&gt; a new postscript operator &amp;&amp;&gt;
<br>&gt;=20
<br>&gt; This is the initial draft. Feedback is welcome.
<br>
<br>I disagree with the motivation you presented, in particular, this point=
:
<br>
<br>=C2=A0 - It is always clear when to use what, using one in the place of=
 the=20
<br>other is in practice always wrong;
<br>
<br>While it is likely clear to the developer which construct to use, this=
=20
<br>knowledge does not follow from the code so that it can be inferred by=
=20
<br>the compiler. The choice of the construct is made by the developer,=20
<br>depending on what he wants to do. For example:
<br>
<br>
<br>=C2=A0 =C2=A0template&lt; typename T &gt;
<br>=C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>=C2=A0 =C2=A0{
<br>=C2=A0 =C2=A0 =C2=A0vec.push_back(std::pass(<wbr>value));
<br>=C2=A0 =C2=A0}
<br>
<br>=C2=A0 =C2=A0std::string str;
<br>=C2=A0 =C2=A0foo(str);
<br>
<br>It is not clear what this code intends to do. If std::pass acts=20
<br>similarly to to std::forward then str is left intact and can be used=20
<br>later. If it is equivalent to std::move then str is empty afterwards. <=
/blockquote><div><br></div><div>Why should there be an &quot;if&quot;? The =
signature of the function is T&amp;&amp; from that alone follows &#39;value=
&#39; is forwarded.=C2=A0</div><div><br></div><div>If one writes a function=
 where he moves instead of forwarding=C2=A0</div><div><br></div><div><br st=
yle=3D"background-attachment: scroll; background-clip: border-box; backgrou=
nd-color: transparent; background-image: none; background-origin: padding-b=
ox; background-position-x: 0%; background-position-y: 0%; background-repeat=
: repeat; background-size: auto; border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 3=
4, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot=
;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; fo=
nt-weight: 400; height: auto; letter-spacing: normal; margin-bottom: 0px; m=
argin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0px; orphan=
s: 2; overflow: visible; overflow-x: visible; overflow-y: visible; padding-=
bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
 -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=C2=A0=
=C2=A0=C2=A0template&lt; typename T &gt;
</span><br style=3D"background-attachment: scroll; background-clip: border-=
box; background-color: transparent; background-image: none; background-orig=
in: padding-box; background-position-x: 0%; background-position-y: 0%; back=
ground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helve=
tica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; height: auto; letter-spacing: normal; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width=
: 0px; orphans: 2; overflow: visible; overflow-x: visible; overflow-y: visi=
ble; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"display: inline !important; float: none; backgro=
und-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2;=
 text-align: left; text-decoration: none; text-indent: 0px; text-transform:=
 none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0=
px;">=C2=A0 =C2=A0void foo(T&amp;&amp; value)
</span><br style=3D"background-attachment: scroll; background-clip: border-=
box; background-color: transparent; background-image: none; background-orig=
in: padding-box; background-position-x: 0%; background-position-y: 0%; back=
ground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helve=
tica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; height: auto; letter-spacing: normal; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width=
: 0px; orphans: 2; overflow: visible; overflow-x: visible; overflow-y: visi=
ble; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"display: inline !important; float: none; backgro=
und-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2;=
 text-align: left; text-decoration: none; text-indent: 0px; text-transform:=
 none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0=
px;">=C2=A0 =C2=A0{
</span><br style=3D"background-attachment: scroll; background-clip: border-=
box; background-color: transparent; background-image: none; background-orig=
in: padding-box; background-position-x: 0%; background-position-y: 0%; back=
ground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helve=
tica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; height: auto; letter-spacing: normal; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width=
: 0px; orphans: 2; overflow: visible; overflow-x: visible; overflow-y: visi=
ble; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"display: inline !important; float: none; backgro=
und-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2;=
 text-align: left; text-decoration: none; text-indent: 0px; text-transform:=
 none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0=
px;">=C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(</span><wbr style=3D"backg=
round-attachment: scroll; background-clip: border-box; background-color: tr=
ansparent; background-image: none; background-origin: padding-box; backgrou=
nd-position-x: 0%; background-position-y: 0%; background-repeat: repeat; ba=
ckground-size: auto; border-bottom-color: rgb(34, 34, 34); border-bottom-st=
yle: none; border-bottom-width: 0px; border-image-outset: 0; border-image-r=
epeat: stretch; border-image-slice: 100%; border-image-source: none; border=
-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: non=
e; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-righ=
t-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); =
border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font=
-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; height: auto; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; min-width: 0px; orphans: 2; overfl=
ow: visible; overflow-x: visible; overflow-y: visible; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span style=
=3D"display: inline !important; float: none; background-color: transparent;=
 color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; f=
ont-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text=
-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-str=
oke-width: 0px; white-space: normal; word-spacing: 0px;">value));
</span><br style=3D"background-attachment: scroll; background-clip: border-=
box; background-color: transparent; background-image: none; background-orig=
in: padding-box; background-position-x: 0%; background-position-y: 0%; back=
ground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helve=
tica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; height: auto; letter-spacing: normal; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width=
: 0px; orphans: 2; overflow: visible; overflow-x: visible; overflow-y: visi=
ble; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"display: inline !important; float: none; backgro=
und-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2;=
 text-align: left; text-decoration: none; text-indent: 0px; text-transform:=
 none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0=
px;">=C2=A0 =C2=A0}=C2=A0</span></div><div><b></b><i></i><u></u><sub></sub>=
<sup></sup><strike></strike><br></div><div>That will be <b>The Wrong Thing<=
/b> to do.</div><div><br></div><div>This is because one <i>lies against the=
 interface </i>- T&amp;&amp; is a forwarding reference,<i> by definition</i=
>.=C2=A0</div><div><br></div><div>Using &quot;object passing&quot;, <i>prev=
ents</i> you to lie!</div><div><br></div><div><br></div><div>See a similar =
post from the original discussion for detailed explanation<br></div><div>ht=
tps://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277=
dtDQAJ<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=
;">
<br>Both interpretations are reasonable and I&#39;ve seen code written both=
 ways=20
<br>in different cases. =C2=A0</blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">
<br>Forwarding and moving a value have a fundamental difference in strength=
..=20
<br>Forwarding does not move the value unless permitted by the program (i.e=
..=20
<br>the value is assumed to be unused afterwards) while std::move is=20
<br>stronger and will move even lvalue. The fact that both may end up movin=
g=20
<br>the value does not mean they are the same and should be expressed the=
=20
<br>same way. Being more explicit about the intent is beneficial to the=20
<br>developer, experienced or junior.
<br></blockquote><div><br></div><div>Question is what is the original inten=
d? And actually the intend in both cases is to give the object away.</div><=
div>This is what the user wants - nothing more nothing less.</div><div>What=
 are the object characteristics before giving it up and in what form the gi=
ve operation takes pace, is of no interest.</div><div><br></div><div><br></=
div><div><br></div><div>About the &quot;ugliness&quot;.=C2=A0</div><div><br=
></div><div>Well, I really hoped a simple &amp;&amp; would do the trick, bu=
t it does clash with the binary operator &amp;&amp; and I see no way around=
 that.</div><div><br></div><div>An alternative might be <font face=3D"couri=
er new,monospace">val~~</font> or<font face=3D"courier new,monospace"> val~=
&amp;&amp; <font face=3D"arial,sans-serif">or just</font> val~ </font><font=
 face=3D"arial,sans-serif">or a keyword </font><font face=3D"courier new,mo=
nospace">val passin.</font></div><div><font face=3D"courier new,monospace">=
<br></font></div><div><font face=3D"arial,sans-serif">See the massive study=
 done in the original post <a href=3D"https://groups.google.com/a/isocpp.or=
g/d/msg/std-proposals/Kdt1dVwL7bo/PNyDb_UEAAAJ">about an operator </a>and <=
a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dV=
wL7bo/r0o4Wy04AQAJ">about a keyword=C2=A0</a></font></div><div><font color=
=3D"#000020"></font><br></div><div>Of course suggestions are welcome.</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/cdb56799-3625-42d5-bbca-2af5fd525eb9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cdb56799-3625-42d5-bbca-2af5fd525eb9=
%40isocpp.org</a>.<br />

------=_Part_46725_356614721.1528439523681--

------=_Part_46724_986399039.1528439523681--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 07 Jun 2018 23:39:13 -0700
Raw View
On Thursday, 7 June 2018 23:32:03 PDT mihailnajdenov@gmail.com wrote:
>    template< typename T >
>    void foo(T&& value)
>    {
>      vec.push_back(std::move(value));
>    }
>
> That will be *The Wrong Thing* to do.
>
> This is because one *lies against the interface *- T&& is a forwarding
> reference,* by definition*.

Except where it isn't.

http://en.cppreference.com/w/cpp/container/vector/push_back

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
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/3426202.gOASAPBTgE%40tjmaciei-mobl1.

.


Author: mihailnajdenov@gmail.com
Date: Thu, 7 Jun 2018 23:53:47 -0700 (PDT)
Raw View
------=_Part_46855_170101864.1528440827633
Content-Type: multipart/alternative;
 boundary="----=_Part_46856_1231393609.1528440827633"

------=_Part_46856_1231393609.1528440827633
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 9:39:17 AM UTC+3, Thiago Macieira wrote:
>
> On Thursday, 7 June 2018 23:32:03 PDT mihailn...@gmail.com <javascript:>
> wrote:
> >    template< typename T >
> >    void foo(T&& value)
> >    {
> >      vec.push_back(std::move(value));
> >    }
> >
> > That will be *The Wrong Thing* to do.
> >
> > This is because one *lies against the interface *- T&& is a forwarding
> > reference,* by definition*.
>
> Except where it isn't.
>
> http://en.cppreference.com/w/cpp/container/vector/push_back
>

I use T&& as a synonym for auto&& or template<class T> auto f(T&&) -
forwarding reference.

push_back interface uses T&& as synonym for value_type&& (actually the
other way around, but you get the idea) - rvalue reference.

Confusions like this are actually one of the arguments *pro* unification of
the passing syntax!


>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>
>
>
>

--
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/c3e2bd5b-393f-43ea-a409-bc6fe84e2d73%40isocpp.org.

------=_Part_46856_1231393609.1528440827633
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 9:39:17 AM UTC+3, Thiag=
o Macieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Thursday, =
7 June 2018 23:32:03 PDT <a onmousedown=3D"this.href=3D&#39;javascript:&#39=
;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" =
href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mail=
to=3D"ks5xHsIUBQAJ">mihailn...@gmail.com</a> wrote:
<br>&gt; =C2=A0 =C2=A0template&lt; typename T &gt;
<br>&gt; =C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>&gt; =C2=A0 =C2=A0{
<br>&gt; =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));
<br>&gt; =C2=A0 =C2=A0}
<br>&gt;=20
<br>&gt; That will be *The Wrong Thing* to do.
<br>&gt;=20
<br>&gt; This is because one *lies against the interface *- T&amp;&amp; is =
a forwarding
<br>&gt; reference,* by definition*.
<br>
<br>Except where it isn&#39;t.
<br>
<br><a onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%=
3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fcontainer%2Fvector%2Fpush_back\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHYD4CSCZUSXH56E0qdc9nvqMuUw&#39;;retur=
n true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A=
%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fcontainer%2Fvector%2Fpush_back\x26sa\=
x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHYD4CSCZUSXH56E0qdc9nvqMuUw&#39;;return =
true;" href=3D"http://en.cppreference.com/w/cpp/container/vector/push_back"=
 target=3D"_blank" rel=3D"nofollow">http://en.cppreference.com/w/<wbr>cpp/c=
ontainer/vector/push_back</a>
<br></blockquote><div><br></div><div>I use <font face=3D"courier new,monosp=
ace">T&amp;&amp; </font><font face=3D"arial,sans-serif">as </font>a synonym=
 for <font face=3D"courier new,monospace">auto&amp;&amp;</font> or <font fa=
ce=3D"courier new,monospace">template&lt;class T&gt; auto f(T&amp;&amp;)</f=
ont> - forwarding reference.</div><div><br></div><div><font color=3D"#00002=
0" face=3D"courier new,monospace">push_back</font><font color=3D"#000020"> =
i</font>nterface uses <font face=3D"courier new,monospace">T&amp;&amp;</fon=
t> as synonym for <font face=3D"Consolas">value_type&amp;&amp; </font>(actu=
ally the other way around, but you get the idea) - rvalue reference.</div><=
div><br></div><div>Confusions like this are actually one of the arguments <=
i>pro</i> unification of the passing syntax!=C2=A0</div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">
<br>--=20
<br>Thiago Macieira - thiago (AT) <a onmousedown=3D"this.href=3D&#39;http:/=
/www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D=
"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fmacieira.info=
\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;=
return true;" href=3D"http://macieira.info" target=3D"_blank" rel=3D"nofoll=
ow">macieira.info</a> - thiago (AT) <a onmousedown=3D"this.href=3D&#39;http=
://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3dD\x26sntz\x3d1\x26=
usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"thi=
s.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fkde.org\x26sa\x3d=
D\x26sntz\x3d1\x26usg\x3dAFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return tru=
e;" href=3D"http://kde.org" target=3D"_blank" rel=3D"nofollow">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>
<br>
<br>
<br></blockquote></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/c3e2bd5b-393f-43ea-a409-bc6fe84e2d73%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c3e2bd5b-393f-43ea-a409-bc6fe84e2d73=
%40isocpp.org</a>.<br />

------=_Part_46856_1231393609.1528440827633--

------=_Part_46855_170101864.1528440827633--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 08 Jun 2018 00:09:57 -0700
Raw View
On Thursday, 7 June 2018 23:53:47 PDT mihailnajdenov@gmail.com wrote:
> Confusions like this are actually one of the arguments *pro* unification of
> the passing syntax!

I don't see how unifying would benefit. If anything, we should have different
syntaxes for the function declarations. That would enable the user to tell
whether the called function will move contents off of the object passed, or
whether it will forward them intact to some other place.

That may enable std::pass() to exist, since the declarations are now
different. But right now, the caller declares whether she wants moving or
forwarding.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center



--
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/2362951.R5znumK4P0%40tjmaciei-mobl1.

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Fri, 8 Jun 2018 11:33:51 +0300
Raw View
On 06/08/18 09:32, mihailnajdenov@gmail.com wrote:
>=20
> If one writes a function where he moves instead of forwarding
>=20
>=20
>  =C2=A0=C2=A0=C2=A0template< typename T >
>  =C2=A0 =C2=A0void foo(T&& value)
>  =C2=A0 =C2=A0{
>  =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(value));
>  =C2=A0 =C2=A0}
> **//___^
> That will be *The Wrong Thing* to do.

There's nothing wrong with it, as long as you actually want to move.

> This is because one /lies against the interface /- T&& is a forwarding=20
> reference,/by definition/.
>=20
> Using "object passing", /prevents/ you to lie!

There's no such thing as a forwarding reference in the language. Using=20
T&&, where T is a template argument, for forwarding is just one use=20
case, but there are also other. For example, this syntax can be used for=20
generalization so that you don't have to write multiple overloads for=20
different argument types.

> See a similar post from the original discussion for detailed explanation
> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gl=
d277dtDQAJ

Using SFINAE to force users to explicitly move is a good approach, but I=20
don't think it is always necessary. If my foo function is called, say,=20
foo_move and is properly documented, there's no reason to force users to=20
explicitly call std::move on their end. Especially, if the user is me,=20
the implementer of foo_move.

>     Forwarding and moving a value have a fundamental difference in
>     strength.
>     Forwarding does not move the value unless permitted by the program
>     (i.e.
>     the value is assumed to be unused afterwards) while std::move is
>     stronger and will move even lvalue. The fact that both may end up
>     moving
>     the value does not mean they are the same and should be expressed the
>     same way. Being more explicit about the intent is beneficial to the
>     developer, experienced or junior.
>=20
> Question is what is the original intend? And actually the intend in both=
=20
> cases is to give the object away.

That's from the function caller's perspective. And as far as the caller=20
is concerned, if you want to move, you use std::move. You never use=20
std::forward to move a value.

As a function implementer (or, more accurately, receiver of the function=20
arguments), you can have different intentions wrt. the arguments. Some=20
of the arguments you may move, others forward, thirds modify or copy. My=20
point is that the compiler is not able and should not be given liberty=20
to decide which behavior to apply in each case. And the end code will=20
have better quality if this intent is apparent.

> About the "ugliness".
>=20
> Well, I really hoped a simple && would do the trick, but it does clash=20
> with the binary operator && and I see no way around that.
>=20
> An alternative might be val~~ or val~&& or just val~ or a keyword val=20
> passin.

These don't look any better to me, sorry. Ignoring for a moment that I=20
don't like the idea to begin with, I would prefer a function-style=20
keyword instead of new obscure operators, especially 3 or more=20
characters long.

--=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/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com=
..

.


Author: mihailnajdenov@gmail.com
Date: Fri, 8 Jun 2018 03:43:27 -0700 (PDT)
Raw View
------=_Part_45336_795789426.1528454607667
Content-Type: multipart/alternative;
 boundary="----=_Part_45337_949700233.1528454607668"

------=_Part_45337_949700233.1528454607668
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:
>
> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
> >
> > If one writes a function where he moves instead of forwarding
> >
> >
> >     template< typename T >
> >     void foo(T&& value)
> >     {
> >       vec.push_back(std::move(value));
> >     }
> > **//___^
> > That will be *The Wrong Thing* to do.
>
> There's nothing wrong with it, as long as you actually want to move.
>
> > This is because one /lies against the interface /- T&& is a forwarding
> > reference,/by definition/.
> >
> > Using "object passing", /prevents/ you to lie!
>
> There's no such thing as a forwarding reference in the language. Using
> T&&, where T is a template argument, for forwarding is just one use
> case, but there are also other. For example, this syntax can be used for
> generalization so that you don't have to write multiple overloads for
> different argument types.
>
> > See a similar post from the original discussion for detailed explanation
> >
> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>
> Using SFINAE to force users to explicitly move is a good approach, but I
> don't think it is always necessary. If my foo function is called, say,
> foo_move and is properly documented, there's no reason to force users to
> explicitly call std::move on their end. Especially, if the user is me,
> the implementer of foo_move.
>


OK, this + Thiago last comment opens an interesting topic.

Are there *any* interfaces, declared (semantically) as auto&& and NOT being
a forwarding reference?

I am sure there isn't a single case in whole std, though I haven't verified
that.

Further, will such an interface be good one. No, hell no.

If one takes an auto&& and does not forwards it - he loses opportunity, he
essentially "drops" the "forwarding reference".
If one takes an auto&& and moves it - he "breaks" the "forwarding reference"
by casting it.

This might not be spelled out in the standard, but that is de-facto the
case - auto&& *IS A *"Forwarding reference".

And it better be! Otherwise this will make C++ even harder to teach and
reason about!


If one declares and interface of type&&, this means "I will take your
soo-to-die-object", hence I can do whatever I want.

However

If one declares and interface of auto&&, this means "I will accept what you
give me", it does *not* mean, "I will take your soo-to-die-of-any-type",
hence I can NOT do whatever I want, otherwise *one is not keeping the
promise of the interface*.

I *promised, *I will *accept *everything*. *

If you pass me a reference to your object and I *pretend* this is soo-to-die
object, it turns out I was lying in the first place -
I don't care about *accepting* everything, I care only about what suits me!

In any case you are free to make foo_move - you have all the tools (and the
reasons) in the world to do so.

I am talking about the default correct behavior out of the box.

Unification of the syntax enforces that correct behavior and makes lying
harder.



>
> >     Forwarding and moving a value have a fundamental difference in
> >     strength.
> >     Forwarding does not move the value unless permitted by the program
> >     (i.e.
> >     the value is assumed to be unused afterwards) while std::move is
> >     stronger and will move even lvalue. The fact that both may end up
> >     moving
> >     the value does not mean they are the same and should be expressed
> the
> >     same way. Being more explicit about the intent is beneficial to the
> >     developer, experienced or junior.
> >
> > Question is what is the original intend? And actually the intend in both
> > cases is to give the object away.
>
> That's from the function caller's perspective. And as far as the caller
> is concerned, if you want to move, you use std::move. You never use
> std::forward to move a value.
>
> As a function implementer (or, more accurately, receiver of the function
> arguments), you can have different intentions wrt. the arguments. Some
> of the arguments you may move, others forward, thirds modify or copy. My
> point is that the compiler is not able and should not be given liberty
> to decide which behavior to apply in each case. And the end code will
> have better quality if this intent is apparent.
>
> > About the "ugliness".
> >
> > Well, I really hoped a simple && would do the trick, but it does clash
> > with the binary operator && and I see no way around that.
> >
> > An alternative might be val~~ or val~&& or just val~ or a keyword val
> > passin.
>
> These don't look any better to me, sorry. Ignoring for a moment that I
> don't like the idea to begin with, I would prefer a function-style
> keyword instead of new obscure operators, especially 3 or more
> characters long.
>

--
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/f8669244-ec84-45f2-a8bc-3c43c4b986c3%40isocpp.org.

------=_Part_45337_949700233.1528454607668
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andr=
ey Semashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 06/08/18 =
09:32, <a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" on=
click=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascript=
:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"9y5YkwMbBQAJ=
">mihailn...@gmail.com</a> wrote:
<br>&gt;=20
<br>&gt; If one writes a function where he moves instead of forwarding
<br>&gt;=20
<br>&gt;=20
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0template&lt; typename T &gt;
<br>&gt; =C2=A0=C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>&gt; =C2=A0=C2=A0 =C2=A0{
<br>&gt; =C2=A0=C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));
<br>&gt; =C2=A0=C2=A0 =C2=A0}
<br>&gt; **//___^
<br>&gt; That will be *The Wrong Thing* to do.
<br>
<br>There&#39;s nothing wrong with it, as long as you actually want to move=
..
<br>
<br>&gt; This is because one /lies against the interface /- T&amp;&amp; is =
a forwarding=20
<br>&gt; reference,/by definition/.
<br>&gt;=20
<br>&gt; Using &quot;object passing&quot;, /prevents/ you to lie!
<br>
<br>There&#39;s no such thing as a forwarding reference in the language. Us=
ing=20
<br>T&amp;&amp;, where T is a template argument, for forwarding is just one=
 use=20
<br>case, but there are also other. For example, this syntax can be used fo=
r=20
<br>generalization so that you don&#39;t have to write multiple overloads f=
or=20
<br>different argument types.
<br>
<br>&gt; See a similar post from the original discussion for detailed expla=
nation
<br>&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/iso=
cpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onc=
lick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-p=
roposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups=
..google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" targ=
et=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/=
d/msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a>
<br>
<br>Using SFINAE to force users to explicitly move is a good approach, but =
I=20
<br>don&#39;t think it is always necessary. If my foo function is called, s=
ay,=20
<br>foo_move and is properly documented, there&#39;s no reason to force use=
rs to=20
<br>explicitly call std::move on their end. Especially, if the user is me,=
=20
<br>the implementer of foo_move.
<br></blockquote><div><br></div><div><br></div><div>OK, this + Thiago last =
comment opens an interesting topic.</div><div><br></div><div>Are there <i>a=
ny</i> interfaces, declared (semantically) as auto&amp;&amp; and NOT being =
a forwarding reference?=C2=A0</div><div><br></div><div>I am sure there isn&=
#39;t a single case in whole std, though I haven&#39;t verified that.=C2=A0=
</div><div><br></div><div>Further, will such an interface be good one. No, =
hell no.</div><div><br></div><div>If one takes an auto&amp;&amp; and does n=
ot forwards it - he loses opportunity, he essentially &quot;drops&quot; the=
 &quot;<span style=3D"display: inline !important; float: none; background-c=
olor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-=
variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text=
-align: left; text-decoration: none; text-indent: 0px; text-transform: none=
; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=
forwarding reference</span>&quot;.</div><div>If one takes an auto&amp;&amp;=
 and moves it - he &quot;breaks&quot; the=C2=A0<span style=3D"display: inli=
ne !important; float: none; background-color: transparent; color: rgb(34, 3=
4, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none=
; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; w=
hite-space: normal; word-spacing: 0px;">&quot;</span><span style=3D"backgro=
und-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); d=
isplay: inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;qu=
ot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; fon=
t-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom:=
 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; pad=
ding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; =
text-align: left; text-decoration: none; text-indent: 0px; text-transform: =
none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0p=
x;">forwarding reference</span><span style=3D"display: inline !important; f=
loat: none; background-color: transparent; color: rgb(34, 34, 34); font-fam=
ily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">&quot; by casting it.</span></div><div><br></div><d=
iv><span style=3D"display: inline !important; float: none; background-color=
: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot=
;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-ali=
gn: left; text-decoration: none; text-indent: 0px; text-transform: none; -w=
ebkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">This=
 might not be spelled out in the standard, but that is de-facto the case - =
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">auto&am=
p;&amp; </span><i style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&am=
p;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: italic;=
 font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2;=
 padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;">IS A </i><span style=3D"display: inline !important; float: none; ba=
ckground-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphan=
s: 2; text-align: left; text-decoration: none; text-indent: 0px; text-trans=
form: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spaci=
ng: 0px;">&quot;Forwarding reference&quot;</span>.=C2=A0</span></div><div><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></sp=
an></div><div><span style=3D"display: inline !important; float: none; backg=
round-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal=
; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: =
2; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
 0px;">And it better be! Otherwise this will make C++ even harder to teach =
and reason about!</span></div><div><span style=3D"display: inline !importan=
t; float: none; background-color: transparent; color: rgb(34, 34, 34); font=
-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; orphans: 2; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;"><br></span></div><div><span style=3D"display: i=
nline !important; float: none; background-color: transparent; color: rgb(34=
, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;=
 font-size: 13px; font-style: normal; font-variant: normal; font-weight: 40=
0; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: n=
one; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px=
; white-space: normal; word-spacing: 0px;"><br></span></div><div><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;">If one declares a=
nd interface of type&amp;&amp;, this means &quot;I will take your soo-to-di=
e-object&quot;, hence I can do whatever I want.</span></div><div><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div>=
<div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-transfor=
m: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; text-decoration: none; word-spacing: 0px; display:=
 inline !important; white-space: normal; orphans: 2; float: none; -webkit-t=
ext-stroke-width: 0px; background-color: transparent;">However</span></div>=
<div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-transfor=
m: none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; text-decoration: none; word-spacing: 0px; display:=
 inline !important; white-space: normal; orphans: 2; float: none; -webkit-t=
ext-stroke-width: 0px; background-color: transparent;"><br></span></div><di=
v><span style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: =
none; text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; text-decoration: none; word-spacing: 0px; display: in=
line !important; white-space: normal; orphans: 2; float: none; -webkit-text=
-stroke-width: 0px; background-color: transparent;">If one <span style=3D"d=
isplay: inline !important; float: none; background-color: transparent; colo=
r: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;">declares and interface =
of auto&amp;&amp;, this means &quot;I will accept what you give me&quot;, i=
t does <i>not</i> mean, &quot;<span style=3D"display: inline !important; fl=
oat: none; background-color: transparent; color: rgb(34, 34, 34); font-fami=
ly: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; fo=
nt-style: normal; font-variant: normal; font-weight: 400; letter-spacing: n=
ormal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0p=
x; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norma=
l; word-spacing: 0px;">I will take your soo-to-die-of-any-type</span>&quot;=
,</span></span></div><div><span style=3D"text-align: left; color: rgb(34, 3=
4, 34); text-transform: none; text-indent: 0px; letter-spacing: normal; fon=
t-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; text-decoration: none; word-s=
pacing: 0px; display: inline !important; white-space: normal; orphans: 2; f=
loat: none; -webkit-text-stroke-width: 0px; background-color: transparent;"=
><span style=3D"display: inline !important; float: none; background-color: =
transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; -web=
kit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">hence =
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">I can N=
OT do whatever I want, otherwise <i>one is not keeping the promise of the i=
nterface</i></span>.</span></span></div><div><span style=3D"text-align: lef=
t; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-s=
pacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-s=
erif; font-size: 13px; font-style: normal; font-variant: normal; text-decor=
ation: none; word-spacing: 0px; display: inline !important; white-space: no=
rmal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-c=
olor: transparent;"><span style=3D"display: inline !important; float: none;=
 background-color: transparent; color: rgb(34, 34, 34); font-family: &quot;=
Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: =
normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orp=
hans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-tr=
ansform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-sp=
acing: 0px;"><br></span></span></div><div><span style=3D"text-align: left; =
color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-spac=
ing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f; font-size: 13px; font-style: normal; font-variant: normal; text-decorati=
on: none; word-spacing: 0px; display: inline !important; white-space: norma=
l; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-colo=
r: transparent;"></span></div><div>I<span style=3D"display: inline !importa=
nt; float: none; background-color: transparent; color: rgb(34, 34, 34); fon=
t-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; orphans: 2; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
 normal; word-spacing: 0px;"> <i>promised, </i>I will <i>accept </i>everyth=
ing<i>.=C2=A0</i></span></div><div><span style=3D"display: inline !importan=
t; float: none; background-color: transparent; color: rgb(34, 34, 34); font=
-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; orphans: 2; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;"><i><br></i></span></div><div><span style=3D"dis=
play: inline !important; float: none; background-color: transparent; color:=
 rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wid=
th: 0px; white-space: normal; word-spacing: 0px;">If you pass me a referenc=
e to your object and I <i>pretend</i> this is=C2=A0<span style=3D"display: =
inline !important; float: none; background-color: transparent; color: rgb(3=
4, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: =
none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0p=
x; white-space: normal; word-spacing: 0px;">soo-to-die object, it turns out=
 I was lying in the first place -</span></span></div><div><span style=3D"di=
splay: inline !important; float: none; background-color: transparent; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wi=
dth: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"display: =
inline !important; float: none; background-color: transparent; color: rgb(3=
4, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: =
none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0p=
x; white-space: normal; word-spacing: 0px;">I don&#39;t care about <i>accep=
ting</i> everything, I care only about what suits me!</span></span></div><d=
iv><span style=3D"display: inline !important; float: none; background-color=
: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot=
;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-ali=
gn: left; text-decoration: none; text-indent: 0px; text-transform: none; -w=
ebkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><i><=
/i><i></i><i></i><i></i><i></i><b></b><i></i><u></u><sub></sub><sup></sup><=
strike></strike><br></span></div><div><span style=3D"display: inline !impor=
tant; float: none; background-color: transparent; color: rgb(34, 34, 34); f=
ont-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: =
13px; font-style: normal; font-variant: normal; font-weight: 400; letter-sp=
acing: normal; orphans: 2; text-align: left; text-decoration: none; text-in=
dent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spac=
e: normal; word-spacing: 0px;">In any case you are free to make foo_move - =
you have all the tools (and the reasons) in the world to do so.</span></div=
><div><span style=3D"display: inline !important; float: none; background-co=
lor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
 -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><=
br></span></div><div><span style=3D"display: inline !important; float: none=
; background-color: transparent; color: rgb(34, 34, 34); font-family: &quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style:=
 normal; font-variant: normal; font-weight: 400; letter-spacing: normal; or=
phans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;">I am talking about the default correct behavior out of the bo=
x.</span></div><div><span style=3D"display: inline !important; float: none;=
 background-color: transparent; color: rgb(34, 34, 34); font-family: &quot;=
Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: =
normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orp=
hans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-tr=
ansform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-sp=
acing: 0px;"><br></span></div><div><span style=3D"display: inline !importan=
t; float: none; background-color: transparent; color: rgb(34, 34, 34); font=
-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; orphans: 2; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;">Unification of the syntax enforces that correct=
 behavior and makes lying harder.=C2=A0</span></div><div><span style=3D"dis=
play: inline !important; float: none; background-color: transparent; color:=
 rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wid=
th: 0px; white-space: normal; word-spacing: 0px;"><br></span></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;">
<br>&gt; =C2=A0 =C2=A0 Forwarding and moving a value have a fundamental dif=
ference in
<br>&gt; =C2=A0 =C2=A0 strength.
<br>&gt; =C2=A0 =C2=A0 Forwarding does not move the value unless permitted =
by the program
<br>&gt; =C2=A0 =C2=A0 (i.e.
<br>&gt; =C2=A0 =C2=A0 the value is assumed to be unused afterwards) while =
std::move is
<br>&gt; =C2=A0 =C2=A0 stronger and will move even lvalue. The fact that bo=
th may end up
<br>&gt; =C2=A0 =C2=A0 moving
<br>&gt; =C2=A0 =C2=A0 the value does not mean they are the same and should=
 be expressed the
<br>&gt; =C2=A0 =C2=A0 same way. Being more explicit about the intent is be=
neficial to the
<br>&gt; =C2=A0 =C2=A0 developer, experienced or junior.
<br>&gt;=20
<br>&gt; Question is what is the original intend? And actually the intend i=
n both=20
<br>&gt; cases is to give the object away.
<br>
<br>That&#39;s from the function caller&#39;s perspective. And as far as th=
e caller=20
<br>is concerned, if you want to move, you use std::move. You never use=20
<br>std::forward to move a value.
<br>
<br>As a function implementer (or, more accurately, receiver of the functio=
n=20
<br>arguments), you can have different intentions wrt. the arguments. Some=
=20
<br>of the arguments you may move, others forward, thirds modify or copy. M=
y=20
<br>point is that the compiler is not able and should not be given liberty=
=20
<br>to decide which behavior to apply in each case. And the end code will=
=20
<br>have better quality if this intent is apparent.
<br>
<br>&gt; About the &quot;ugliness&quot;.
<br>&gt;=20
<br>&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but i=
t does clash=20
<br>&gt; with the binary operator &amp;&amp; and I see no way around that.
<br>&gt;=20
<br>&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a =
keyword val=20
<br>&gt; passin.
<br>
<br>These don&#39;t look any better to me, sorry. Ignoring for a moment tha=
t I=20
<br>don&#39;t like the idea to begin with, I would prefer a function-style=
=20
<br>keyword instead of new obscure operators, especially 3 or more=20
<br>characters long.=C2=A0<br></blockquote></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/f8669244-ec84-45f2-a8bc-3c43c4b986c3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f8669244-ec84-45f2-a8bc-3c43c4b986c3=
%40isocpp.org</a>.<br />

------=_Part_45337_949700233.1528454607668--

------=_Part_45336_795789426.1528454607667--

.


Author: florian.csdt@gmail.com
Date: Fri, 8 Jun 2018 04:34:30 -0700 (PDT)
Raw View
------=_Part_61574_1475371207.1528457670996
Content-Type: multipart/alternative;
 boundary="----=_Part_61575_1870073047.1528457670997"

------=_Part_61575_1870073047.1528457670997
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Another way to see it is:

Both when you forward and when you move, you promise you will not touch the=
=20
object again (except for rebinding it to another value).
I think that's the key point of this proposal.

I envision the following rules:
decltype(x) | decltype(x&&>)
------------|----------------
T           | T&&
T&          | T&
T&&         | T&&
const T     | const T&& // implicitely convertible to const T&
const T&    | const T&
const T&&   | const T&&

When x is an identifier, it will be equivalent to=20
std::forward<decltype(x)>(x), and also std::move(x) if in addition x is not=
=20
a ref.
Those are the most common cases.

However, this new operator cannot move a ref like std::move does.
And they are cases when you really want to do that:
template <class T>
void swap(T& a, T& b) {
  // decltype(a   ) -> T&
  // decltype(a&&>) -> T&
  // decltype(std::move(a)) -> T&&

  T c =3D std::move(a);
  a =3D std::move(b);
  c =3D std::move(c);
}
The swap function cannot be implemented using the "giving up" operator (nor=
=20
is it lying about its interface).
So there are some use-cases for std::move that are not covered by this=20
operator: keeping std::move is needed.

This proposal is still interesting for the most common cases where you=20
don't move a reference but a local variable, and for all the forwarding.
But it should also account for the other not covered use-cases.

Florian


Le vendredi 8 juin 2018 12:43:27 UTC+2, mihailn...@gmail.com a =C3=A9crit :
>
>
>
> On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:
>>
>> On 06/08/18 09:32, mihailn...@gmail.com wrote:=20
>> >=20
>> > If one writes a function where he moves instead of forwarding=20
>> >=20
>> >=20
>> >     template< typename T >=20
>> >     void foo(T&& value)=20
>> >     {=20
>> >       vec.push_back(std::move(value));=20
>> >     }=20
>> > **//___^=20
>> > That will be *The Wrong Thing* to do.=20
>>
>> There's nothing wrong with it, as long as you actually want to move.=20
>>
>> > This is because one /lies against the interface /- T&& is a forwarding=
=20
>> > reference,/by definition/.=20
>> >=20
>> > Using "object passing", /prevents/ you to lie!=20
>>
>> There's no such thing as a forwarding reference in the language. Using=
=20
>> T&&, where T is a template argument, for forwarding is just one use=20
>> case, but there are also other. For example, this syntax can be used for=
=20
>> generalization so that you don't have to write multiple overloads for=20
>> different argument types.=20
>>
>> > See a similar post from the original discussion for detailed=20
>> explanation=20
>> >=20
>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/G=
ld277dtDQAJ=20
>>
>> Using SFINAE to force users to explicitly move is a good approach, but I=
=20
>> don't think it is always necessary. If my foo function is called, say,=
=20
>> foo_move and is properly documented, there's no reason to force users to=
=20
>> explicitly call std::move on their end. Especially, if the user is me,=
=20
>> the implementer of foo_move.=20
>>
>
>
> OK, this + Thiago last comment opens an interesting topic.
>
> Are there *any* interfaces, declared (semantically) as auto&& and NOT=20
> being a forwarding reference?=20
>
> I am sure there isn't a single case in whole std, though I haven't=20
> verified that.=20
>
> Further, will such an interface be good one. No, hell no.
>
> If one takes an auto&& and does not forwards it - he loses opportunity, h=
e=20
> essentially "drops" the "forwarding reference".
> If one takes an auto&& and moves it - he "breaks" the "forwarding=20
> reference" by casting it.
>
> This might not be spelled out in the standard, but that is de-facto the=
=20
> case - auto&& *IS A *"Forwarding reference".=20
>
> And it better be! Otherwise this will make C++ even harder to teach and=
=20
> reason about!
>
>
> If one declares and interface of type&&, this means "I will take your=20
> soo-to-die-object", hence I can do whatever I want.
>
> However
>
> If one declares and interface of auto&&, this means "I will accept what=
=20
> you give me", it does *not* mean, "I will take your soo-to-die-of-any-typ=
e
> ",
> hence I can NOT do whatever I want, otherwise *one is not keeping the=20
> promise of the interface*.
>
> I *promised, *I will *accept *everything*. *
>
> If you pass me a reference to your object and I *pretend* this is soo-to-=
die=20
> object, it turns out I was lying in the first place -
> I don't care about *accepting* everything, I care only about what suits=
=20
> me!
>
> In any case you are free to make foo_move - you have all the tools (and=
=20
> the reasons) in the world to do so.
>
> I am talking about the default correct behavior out of the box.
>
> Unification of the syntax enforces that correct behavior and makes lying=
=20
> harder.=20
>
> =20
>
>>
>> >     Forwarding and moving a value have a fundamental difference in=20
>> >     strength.=20
>> >     Forwarding does not move the value unless permitted by the program=
=20
>> >     (i.e.=20
>> >     the value is assumed to be unused afterwards) while std::move is=
=20
>> >     stronger and will move even lvalue. The fact that both may end up=
=20
>> >     moving=20
>> >     the value does not mean they are the same and should be expressed=
=20
>> the=20
>> >     same way. Being more explicit about the intent is beneficial to th=
e=20
>> >     developer, experienced or junior.=20
>> >=20
>> > Question is what is the original intend? And actually the intend in=20
>> both=20
>> > cases is to give the object away.=20
>>
>> That's from the function caller's perspective. And as far as the caller=
=20
>> is concerned, if you want to move, you use std::move. You never use=20
>> std::forward to move a value.=20
>>
>> As a function implementer (or, more accurately, receiver of the function=
=20
>> arguments), you can have different intentions wrt. the arguments. Some=
=20
>> of the arguments you may move, others forward, thirds modify or copy. My=
=20
>> point is that the compiler is not able and should not be given liberty=
=20
>> to decide which behavior to apply in each case. And the end code will=20
>> have better quality if this intent is apparent.=20
>>
>> > About the "ugliness".=20
>> >=20
>> > Well, I really hoped a simple && would do the trick, but it does clash=
=20
>> > with the binary operator && and I see no way around that.=20
>> >=20
>> > An alternative might be val~~ or val~&& or just val~ or a keyword val=
=20
>> > passin.=20
>>
>> These don't look any better to me, sorry. Ignoring for a moment that I=
=20
>> don't like the idea to begin with, I would prefer a function-style=20
>> keyword instead of new obscure operators, especially 3 or more=20
>> characters long.=20
>>
>

--=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/e5715a20-0d75-45ce-a646-0d2644c2f9db%40isocpp.or=
g.

------=_Part_61575_1870073047.1528457670997
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Another way to see it is:<br><br>Both when you forward and=
 when you move, you promise you will not touch the object again (except for=
 rebinding it to another value).<br>I think that&#39;s the key point of thi=
s proposal.<br><br>I envision the following rules:<br><span style=3D"font-f=
amily: courier new, monospace;">decltype(x) | decltype(x&amp;&amp;&gt;)<br>=
------------|----------------<br>T=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>T&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;<br>T&amp;&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>const T=C2=A0=C2=A0=C2=A0=C2=A0 | co=
nst T&amp;&amp; // implicitely convertible to const T&amp;<br>const T&amp;=
=C2=A0=C2=A0=C2=A0 | const T&amp;<br>const T&amp;&amp;=C2=A0=C2=A0 | const =
T&amp;&amp;<br></span><br>When <span style=3D"font-family: courier new, mon=
ospace;">x</span> is an identifier, it will be equivalent to <span style=3D=
"font-family: courier new, monospace;">std::forward&lt;decltype(x)&gt;(x)</=
span>, and also <span style=3D"font-family: courier new, monospace;">std::m=
ove(x)</span> if in addition <span style=3D"font-family: courier new, monos=
pace;">x</span> is not a ref.<br>Those are the most common cases.<br><br>Ho=
wever, this new operator cannot move a ref like <span style=3D"font-family:=
 courier new, monospace;">std::move</span> does.<br>And they are cases when=
 you really want to do that:<br><div style=3D"background-color: rgb(250, 25=
0, 250); border-color: rgb(187, 187, 187); border-style: solid; border-widt=
h: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> T</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: #008;" class=3D"styled-by-prettify">void</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> swap</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</s=
pan><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: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">// decltype(a =C2=A0 ) -&gt; T&amp;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">// decltype(a=
&amp;&amp;&gt;) -&gt; T&amp;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">// decltype(std::move(a)) -&gt; T&amp;&amp;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 T c </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">move</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">a</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 a </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> 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><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">b</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 c </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-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>c</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></span></div></code></div>T=
he swap function cannot be implemented using the &quot;giving up&quot; oper=
ator (nor is it lying about its interface).<br>So there are some use-cases =
for <span style=3D"font-family: courier new, monospace;">std::move</span> t=
hat are not covered by this operator: keeping <span style=3D"font-family: c=
ourier new, monospace;">std::move</span> is needed.<br><br>This proposal is=
 still interesting for the most common cases where you don&#39;t move a ref=
erence but a local variable, and for all the forwarding.<br>But it should a=
lso account for the other not covered use-cases.<br><br>Florian<br><br><br>=
Le vendredi 8 juin 2018 12:43:27 UTC+2, mihailn...@gmail.com a =C3=A9crit=
=C2=A0:<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"><br><b=
r>On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex">On 06/08/18 09:32, <a rel=3D"nofollow">m=
ihailn...@gmail.com</a> wrote:
<br>&gt;=20
<br>&gt; If one writes a function where he moves instead of forwarding
<br>&gt;=20
<br>&gt;=20
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0template&lt; typename T &gt;
<br>&gt; =C2=A0=C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>&gt; =C2=A0=C2=A0 =C2=A0{
<br>&gt; =C2=A0=C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));
<br>&gt; =C2=A0=C2=A0 =C2=A0}
<br>&gt; **//___^
<br>&gt; That will be *The Wrong Thing* to do.
<br>
<br>There&#39;s nothing wrong with it, as long as you actually want to move=
..
<br>
<br>&gt; This is because one /lies against the interface /- T&amp;&amp; is =
a forwarding=20
<br>&gt; reference,/by definition/.
<br>&gt;=20
<br>&gt; Using &quot;object passing&quot;, /prevents/ you to lie!
<br>
<br>There&#39;s no such thing as a forwarding reference in the language. Us=
ing=20
<br>T&amp;&amp;, where T is a template argument, for forwarding is just one=
 use=20
<br>case, but there are also other. For example, this syntax can be used fo=
r=20
<br>generalization so that you don&#39;t have to write multiple overloads f=
or=20
<br>different argument types.
<br>
<br>&gt; See a similar post from the original discussion for detailed expla=
nation
<br>&gt; <a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-propos=
als/Kdt1dVwL7bo/Gld277dtDQAJ" rel=3D"nofollow" target=3D"_blank" onmousedow=
n=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-prop=
osals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=3D"this.href=3D&#=
39;https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/G=
ld277dtDQAJ&#39;;return true;">https://groups.google.com/a/<wbr>isocpp.org/=
d/msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a>
<br>
<br>Using SFINAE to force users to explicitly move is a good approach, but =
I=20
<br>don&#39;t think it is always necessary. If my foo function is called, s=
ay,=20
<br>foo_move and is properly documented, there&#39;s no reason to force use=
rs to=20
<br>explicitly call std::move on their end. Especially, if the user is me,=
=20
<br>the implementer of foo_move.
<br></blockquote><div><br></div><div><br></div><div>OK, this + Thiago last =
comment opens an interesting topic.</div><div><br></div><div>Are there <i>a=
ny</i> interfaces, declared (semantically) as auto&amp;&amp; and NOT being =
a forwarding reference?=C2=A0</div><div><br></div><div>I am sure there isn&=
#39;t a single case in whole std, though I haven&#39;t verified that.=C2=A0=
</div><div><br></div><div>Further, will such an interface be good one. No, =
hell no.</div><div><br></div><div>If one takes an auto&amp;&amp; and does n=
ot forwards it - he loses opportunity, he essentially &quot;drops&quot; the=
 &quot;<span style=3D"display:inline!important;float:none;background-color:=
transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">forw=
arding reference</span>&quot;.</div><div>If one takes an auto&amp;&amp; and=
 moves it - he &quot;breaks&quot; the=C2=A0<span style=3D"display:inline!im=
portant;float:none;background-color:transparent;color:rgb(34,34,34);font-fa=
mily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">&quot;</span><span>forwarding reference</sp=
an><span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-w=
eight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px">&quot; b=
y casting it.</span></div><div><br></div><div><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">This might not be spelled out in the sta=
ndard, but that is de-facto the case - <span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">auto&amp;&amp; </span><i>IS A </i><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px">&quot;Forwarding refer=
ence&quot;</span>.=C2=A0</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">And it better be! Otherwise this =
will make C++ even harder to teach and reason about!</span></div><div><span=
 style=3D"display:inline!important;float:none;background-color:transparent;=
color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:40=
0;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px"><br></span></div=
><div><span style=3D"display:inline!important;float:none;background-color:t=
ransparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fon=
t-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><=
/span></div><div><span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant=
:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorati=
on:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">If one declares and interface of type&amp;&amp;, this means &quot;I w=
ill take your soo-to-die-object&quot;, hence I can do whatever I want.</spa=
n></div><div><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);=
text-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:nor=
mal;font-variant:normal;text-decoration:none;word-spacing:0px;display:inlin=
e!important;white-space:normal;float:none;background-color:transparent">How=
ever</span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);te=
xt-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norma=
l;font-variant:normal;text-decoration:none;word-spacing:0px;display:inline!=
important;white-space:normal;float:none;background-color:transparent"><br><=
/span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);text-tr=
ansform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;text-decoration:none;word-spacing:0px;display:inline!impor=
tant;white-space:normal;float:none;background-color:transparent">If one <sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">declares and i=
nterface of auto&amp;&amp;, this means &quot;I will accept what you give me=
&quot;, it does <i>not</i> mean, &quot;<span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">I will take your soo-to-die-of-any-type</span>&=
quot;,</span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"><span style=3D"display:inline!important;float:none;background-color:tra=
nsparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-=
weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px">hence <=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px">I can NOT do=
 whatever I want, otherwise <i>one is not keeping the promise of the interf=
ace</i></span>.</span></span></div><div><span style=3D"text-align:left;colo=
r:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;text-decoration:none;word-spacing:0=
px;display:inline!important;white-space:normal;float:none;background-color:=
transparent"><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"></span></div><div>I<span style=3D"display:inline!important;float:none;b=
ackground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quo=
t;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-v=
ariant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-de=
coration:none;text-indent:0px;text-transform:none;white-space:normal;word-s=
pacing:0px"> <i>promised, </i>I will <i>accept </i>everything<i>.=C2=A0</i>=
</span></div><div><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><i><br></i></span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px">If you pass me a reference to your object and I <i=
>pretend</i> this is=C2=A0<span style=3D"display:inline!important;float:non=
e;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text=
-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px">soo-to-die object, it turns out I was lying in the first pla=
ce -</span></span></div><div><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px">I don&#39;t care about <i>accepting</i> everything, I care only abou=
t what suits me!</span></span></div><div><span style=3D"display:inline!impo=
rtant;float:none;background-color:transparent;color:rgb(34,34,34);font-fami=
ly:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-s=
tyle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-=
align:left;text-decoration:none;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px"><i></i><i></i><i></i><i></i><i></i><b></b><i>=
</i><u></u><sub></sub><sup></sup><strike></strike><br></span></div><div><sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">In any case yo=
u are free to make foo_move - you have all the tools (and the reasons) in t=
he world to do so.</span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px"><br></span></div><div><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px">I am talking about the default correct =
behavior out of the box.</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">Unification of the syntax enforce=
s that correct behavior and makes lying harder.=C2=A0</span></div><div><spa=
n style=3D"display:inline!important;float:none;background-color:transparent=
;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:4=
00;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px"><br></span></di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>&gt; =C2=A0 =C2=A0 Forwarding and moving a value have a fundamental dif=
ference in
<br>&gt; =C2=A0 =C2=A0 strength.
<br>&gt; =C2=A0 =C2=A0 Forwarding does not move the value unless permitted =
by the program
<br>&gt; =C2=A0 =C2=A0 (i.e.
<br>&gt; =C2=A0 =C2=A0 the value is assumed to be unused afterwards) while =
std::move is
<br>&gt; =C2=A0 =C2=A0 stronger and will move even lvalue. The fact that bo=
th may end up
<br>&gt; =C2=A0 =C2=A0 moving
<br>&gt; =C2=A0 =C2=A0 the value does not mean they are the same and should=
 be expressed the
<br>&gt; =C2=A0 =C2=A0 same way. Being more explicit about the intent is be=
neficial to the
<br>&gt; =C2=A0 =C2=A0 developer, experienced or junior.
<br>&gt;=20
<br>&gt; Question is what is the original intend? And actually the intend i=
n both=20
<br>&gt; cases is to give the object away.
<br>
<br>That&#39;s from the function caller&#39;s perspective. And as far as th=
e caller=20
<br>is concerned, if you want to move, you use std::move. You never use=20
<br>std::forward to move a value.
<br>
<br>As a function implementer (or, more accurately, receiver of the functio=
n=20
<br>arguments), you can have different intentions wrt. the arguments. Some=
=20
<br>of the arguments you may move, others forward, thirds modify or copy. M=
y=20
<br>point is that the compiler is not able and should not be given liberty=
=20
<br>to decide which behavior to apply in each case. And the end code will=
=20
<br>have better quality if this intent is apparent.
<br>
<br>&gt; About the &quot;ugliness&quot;.
<br>&gt;=20
<br>&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but i=
t does clash=20
<br>&gt; with the binary operator &amp;&amp; and I see no way around that.
<br>&gt;=20
<br>&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a =
keyword val=20
<br>&gt; passin.
<br>
<br>These don&#39;t look any better to me, sorry. Ignoring for a moment tha=
t I=20
<br>don&#39;t like the idea to begin with, I would prefer a function-style=
=20
<br>keyword instead of new obscure operators, especially 3 or more=20
<br>characters long.=C2=A0<br></blockquote></div></blockquote></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/e5715a20-0d75-45ce-a646-0d2644c2f9db%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e5715a20-0d75-45ce-a646-0d2644c2f9db=
%40isocpp.org</a>.<br />

------=_Part_61575_1870073047.1528457670997--

------=_Part_61574_1475371207.1528457670996--

.


Author: mihailnajdenov@gmail.com
Date: Fri, 8 Jun 2018 05:05:11 -0700 (PDT)
Raw View
------=_Part_61448_699966038.1528459511635
Content-Type: multipart/alternative;
 boundary="----=_Part_61449_1255623196.1528459511636"

------=_Part_61449_1255623196.1528459511636
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, June 8, 2018 at 2:34:31 PM UTC+3, floria...@gmail.com wrote:
>
> Another way to see it is:
>
> Both when you forward and when you move, you promise you will not touch=
=20
> the object again (except for rebinding it to another value).
>


In the case of forwarding reference you can't even rebind or at least you=
=20
should not, much the same way you should not move a frw ref.=20

=20

> I think that's the key point of this proposal.
>
> I envision the following rules:
> decltype(x) | decltype(x&&>)
> ------------|----------------
> T           | T&&
> T&          | T&
> T&&         | T&&
> const T     | const T&& // implicitely convertible to const T&
> const T&    | const T&
> const T&&   | const T&&
>
> When x is an identifier, it will be equivalent to=20
> std::forward<decltype(x)>(x), and also std::move(x) if in addition x is=
=20
> not a ref.
> Those are the most common cases.
>
> However, this new operator cannot move a ref like std::move does.
>



Currently the proposal moves in all cases *except* if the identifier is=20
"forwarding reference". This is - forward *iff*  decltype(x) =3D=3D=20
substitutedType&&

This will make it behave the same way move and forward are used today.

Yes there are cases of moving a mutating ref. Not just in swap

void merge(forward_list&& __list)
{ merge(std::move(__list), std::less<_Tp>()); }
void
merge(forward_list& __list)
{ merge(std::move(__list)); }


This should work as well under the unified syntax. It will move in *both*=
=20
cases as __list is *not* substitutedType&&


=20

> And they are cases when you really want to do that:
> template <class T>
> void swap(T& a, T& b) {
>   // decltype(a   ) -> T&
>   // decltype(a&&>) -> T&
>   // decltype(std::move(a)) -> T&&
>
>   T c =3D std::move(a);
>   a =3D std::move(b);
>   c =3D std::move(c);
> }
> The swap function cannot be implemented using the "giving up" operator=20
> (nor is it lying about its interface).
> So there are some use-cases for std::move that are not covered by this=20
> operator: keeping std::move is needed.
>
> This proposal is still interesting for the most common cases where you=20
> don't move a reference but a local variable, and for all the forwarding.
> But it should also account for the other not covered use-cases.
>
> Florian
>
>
> Le vendredi 8 juin 2018 12:43:27 UTC+2, mihailn...@gmail.com a =C3=A9crit=
 :
>>
>>
>>
>> On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:
>>>
>>> On 06/08/18 09:32, mihailn...@gmail.com wrote:=20
>>> >=20
>>> > If one writes a function where he moves instead of forwarding=20
>>> >=20
>>> >=20
>>> >     template< typename T >=20
>>> >     void foo(T&& value)=20
>>> >     {=20
>>> >       vec.push_back(std::move(value));=20
>>> >     }=20
>>> > **//___^=20
>>> > That will be *The Wrong Thing* to do.=20
>>>
>>> There's nothing wrong with it, as long as you actually want to move.=20
>>>
>>> > This is because one /lies against the interface /- T&& is a forwardin=
g=20
>>> > reference,/by definition/.=20
>>> >=20
>>> > Using "object passing", /prevents/ you to lie!=20
>>>
>>> There's no such thing as a forwarding reference in the language. Using=
=20
>>> T&&, where T is a template argument, for forwarding is just one use=20
>>> case, but there are also other. For example, this syntax can be used fo=
r=20
>>> generalization so that you don't have to write multiple overloads for=
=20
>>> different argument types.=20
>>>
>>> > See a similar post from the original discussion for detailed=20
>>> explanation=20
>>> >=20
>>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/=
Gld277dtDQAJ=20
>>>
>>> Using SFINAE to force users to explicitly move is a good approach, but =
I=20
>>> don't think it is always necessary. If my foo function is called, say,=
=20
>>> foo_move and is properly documented, there's no reason to force users t=
o=20
>>> explicitly call std::move on their end. Especially, if the user is me,=
=20
>>> the implementer of foo_move.=20
>>>
>>
>>
>> OK, this + Thiago last comment opens an interesting topic.
>>
>> Are there *any* interfaces, declared (semantically) as auto&& and NOT=20
>> being a forwarding reference?=20
>>
>> I am sure there isn't a single case in whole std, though I haven't=20
>> verified that.=20
>>
>> Further, will such an interface be good one. No, hell no.
>>
>> If one takes an auto&& and does not forwards it - he loses opportunity,=
=20
>> he essentially "drops" the "forwarding reference".
>> If one takes an auto&& and moves it - he "breaks" the "forwarding=20
>> reference" by casting it.
>>
>> This might not be spelled out in the standard, but that is de-facto the=
=20
>> case - auto&& *IS A *"Forwarding reference".=20
>>
>> And it better be! Otherwise this will make C++ even harder to teach and=
=20
>> reason about!
>>
>>
>> If one declares and interface of type&&, this means "I will take your=20
>> soo-to-die-object", hence I can do whatever I want.
>>
>> However
>>
>> If one declares and interface of auto&&, this means "I will accept what=
=20
>> you give me", it does *not* mean, "I will take your=20
>> soo-to-die-of-any-type",
>> hence I can NOT do whatever I want, otherwise *one is not keeping the=20
>> promise of the interface*.
>>
>> I *promised, *I will *accept *everything*. *
>>
>> If you pass me a reference to your object and I *pretend* this is soo-to=
-die=20
>> object, it turns out I was lying in the first place -
>> I don't care about *accepting* everything, I care only about what suits=
=20
>> me!
>>
>> In any case you are free to make foo_move - you have all the tools (and=
=20
>> the reasons) in the world to do so.
>>
>> I am talking about the default correct behavior out of the box.
>>
>> Unification of the syntax enforces that correct behavior and makes lying=
=20
>> harder.=20
>>
>> =20
>>
>>>
>>> >     Forwarding and moving a value have a fundamental difference in=20
>>> >     strength.=20
>>> >     Forwarding does not move the value unless permitted by the progra=
m=20
>>> >     (i.e.=20
>>> >     the value is assumed to be unused afterwards) while std::move is=
=20
>>> >     stronger and will move even lvalue. The fact that both may end up=
=20
>>> >     moving=20
>>> >     the value does not mean they are the same and should be expressed=
=20
>>> the=20
>>> >     same way. Being more explicit about the intent is beneficial to=
=20
>>> the=20
>>> >     developer, experienced or junior.=20
>>> >=20
>>> > Question is what is the original intend? And actually the intend in=
=20
>>> both=20
>>> > cases is to give the object away.=20
>>>
>>> That's from the function caller's perspective. And as far as the caller=
=20
>>> is concerned, if you want to move, you use std::move. You never use=20
>>> std::forward to move a value.=20
>>>
>>> As a function implementer (or, more accurately, receiver of the functio=
n=20
>>> arguments), you can have different intentions wrt. the arguments. Some=
=20
>>> of the arguments you may move, others forward, thirds modify or copy. M=
y=20
>>> point is that the compiler is not able and should not be given liberty=
=20
>>> to decide which behavior to apply in each case. And the end code will=
=20
>>> have better quality if this intent is apparent.=20
>>>
>>> > About the "ugliness".=20
>>> >=20
>>> > Well, I really hoped a simple && would do the trick, but it does clas=
h=20
>>> > with the binary operator && and I see no way around that.=20
>>> >=20
>>> > An alternative might be val~~ or val~&& or just val~ or a keyword val=
=20
>>> > passin.=20
>>>
>>> These don't look any better to me, sorry. Ignoring for a moment that I=
=20
>>> don't like the idea to begin with, I would prefer a function-style=20
>>> keyword instead of new obscure operators, especially 3 or more=20
>>> characters long.=20
>>>
>>

--=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/d689e667-19c2-4e32-be9f-5c040da3eab5%40isocpp.or=
g.

------=_Part_61449_1255623196.1528459511636
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 2:34:31 PM UTC+3, flori=
a...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Another way to see it is:<br><br>Both when you forward and when yo=
u move, you promise you will not touch the object again (except for rebindi=
ng it to another value).<br></div></blockquote><div><br></div><div><br></di=
v><div>In the case of forwarding reference you can&#39;t even rebind or at =
least you should not, much the same way you should not move a frw ref.=C2=
=A0</div><div><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">I think that&#39;s the key point of this propos=
al.<br><br>I envision the following rules:<br><span style=3D"font-family:co=
urier new,monospace">decltype(x) | decltype(x&amp;&amp;&gt;)<br>-----------=
-|----------------<br>T=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 | T&amp;&amp;<br>T&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 | T&amp;<br>T&amp;&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 | T&amp;&amp;<br>const T=C2=A0=C2=A0=C2=A0=C2=A0 | const T&amp;&a=
mp; // implicitely convertible to const T&amp;<br>const T&amp;=C2=A0=C2=A0=
=C2=A0 | const T&amp;<br>const T&amp;&amp;=C2=A0=C2=A0 | const T&amp;&amp;<=
br></span><br>When <span style=3D"font-family:courier new,monospace">x</spa=
n> is an identifier, it will be equivalent to <span style=3D"font-family:co=
urier new,monospace">std::forward&lt;decltype(x)&gt;(x)</span>, and also <s=
pan style=3D"font-family:courier new,monospace">std::move(x)</span> if in a=
ddition <span style=3D"font-family:courier new,monospace">x</span> is not a=
 ref.<br>Those are the most common cases.<br><br>However, this new operator=
 cannot move a ref like <span style=3D"font-family:courier new,monospace">s=
td::move</span> does.<br></div></blockquote><div><br></div><div><br></div><=
div><br></div><div>Currently the proposal moves in all cases <i>except</i> =
if the identifier is &quot;forwarding reference&quot;. This is - forward <b=
>iff</b>=C2=A0 <font face=3D"courier new,monospace"><span style=3D"text-ali=
gn: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; l=
etter-spacing: normal; font-size: 13px; font-style: normal; font-variant: n=
ormal; font-weight: 400; text-decoration: none; word-spacing: 0px; display:=
 inline !important; white-space: normal; orphans: 2; float: none; -webkit-t=
ext-stroke-width: 0px; background-color: transparent;">decltype(x) =3D=3D <=
/span>substitutedType&amp;&amp;</font></div><div><font face=3D"courier new,=
monospace"></font><br></div><div>This will make it behave the same way move=
 and forward are used today.</div><div><br></div><div>Yes there are cases o=
f moving a mutating ref. Not just in swap</div><font face=3D"courier new,mo=
nospace"><br> void merge(forward_list&amp;&amp; __list)<br> { merge(std::mo=
ve(__list), std::less&lt;_Tp&gt;()); }<br> void<br> merge(forward_list&amp;=
 __list)<br></font><div><font face=3D"courier new,monospace"> { merge(std::=
move(__list)); }</font></div><div><br></div><div><br></div><div>This should=
 work as well under the unified syntax. It will move in <i>both</i> cases a=
s<font face=3D"courier new,monospace"> __list</font> is <b>not</b>=C2=A0<sp=
an style=3D"background-color: transparent; border-bottom-color: rgb(34, 34,=
 34); border-bottom-style: none; border-bottom-width: 0px; border-image-out=
set: 0; border-image-repeat: stretch; border-image-slice: 100%; border-imag=
e-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); =
border-left-style: none; border-left-width: 0px; border-right-color: rgb(34=
, 34, 34); border-right-style: none; border-right-width: 0px; border-top-co=
lor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color:=
 rgb(34, 34, 34); display: inline; float: none; font-family: courier new,mo=
nospace; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; ma=
rgin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"></span><span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: courier new,monospace; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">substitutedType&amp;&amp;</span></div><div><b></b><=
i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><div><br></di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">And they are cases when you really want to do that:<br><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px"><code><div><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</spa=
n><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">void</span><span style=3D"color:#000"> swap</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">T</span>=
<span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> a</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> T</span><spa=
n style=3D"color:#660">&amp;</span><span style=3D"color:#000"> b</span><spa=
n style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><spa=
n style=3D"color:#800">// decltype(a =C2=A0 ) -&gt; T&amp;</span><span styl=
e=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#800">// decltype(a=
&amp;&amp;&gt;) -&gt; T&amp;</span><span style=3D"color:#000"><br>=C2=A0 </=
span><span style=3D"color:#800">// decltype(std::move(a)) -&gt; T&amp;&amp;=
</span><span style=3D"color:#000"><br><br>=C2=A0 T c </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">move</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">a</span><span style=3D"color:=
#660">);</span><span style=3D"color:#000"><br>=C2=A0 a </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">move</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">b</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br>=C2=A0 c </span><span st=
yle=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><span st=
yle=3D"color:#660">::</span><span style=3D"color:#000">move</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">c</span><span style=3D=
"color:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#660">}</span><span style=3D"color:#000"><br></span></div></code></di=
v>The swap function cannot be implemented using the &quot;giving up&quot; o=
perator (nor is it lying about its interface).<br>So there are some use-cas=
es for <span style=3D"font-family:courier new,monospace">std::move</span> t=
hat are not covered by this operator: keeping <span style=3D"font-family:co=
urier new,monospace">std::move</span> is needed.<br><br>This proposal is st=
ill interesting for the most common cases where you don&#39;t move a refere=
nce but a local variable, and for all the forwarding.<br>But it should also=
 account for the other not covered use-cases.<br><br>Florian<br><br><br>Le =
vendredi 8 juin 2018 12:43:27 UTC+2, <a>mihailn...@gmail.com</a> a =C3=A9cr=
it=C2=A0:<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"><br><br>O=
n Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex">On 06/08/18 09:32, <a rel=3D"nofollow">miha=
iln...@gmail.com</a> wrote:
<br>&gt;=20
<br>&gt; If one writes a function where he moves instead of forwarding
<br>&gt;=20
<br>&gt;=20
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0template&lt; typename T &gt;
<br>&gt; =C2=A0=C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>&gt; =C2=A0=C2=A0 =C2=A0{
<br>&gt; =C2=A0=C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));
<br>&gt; =C2=A0=C2=A0 =C2=A0}
<br>&gt; **//___^
<br>&gt; That will be *The Wrong Thing* to do.
<br>
<br>There&#39;s nothing wrong with it, as long as you actually want to move=
..
<br>
<br>&gt; This is because one /lies against the interface /- T&amp;&amp; is =
a forwarding=20
<br>&gt; reference,/by definition/.
<br>&gt;=20
<br>&gt; Using &quot;object passing&quot;, /prevents/ you to lie!
<br>
<br>There&#39;s no such thing as a forwarding reference in the language. Us=
ing=20
<br>T&amp;&amp;, where T is a template argument, for forwarding is just one=
 use=20
<br>case, but there are also other. For example, this syntax can be used fo=
r=20
<br>generalization so that you don&#39;t have to write multiple overloads f=
or=20
<br>different argument types.
<br>
<br>&gt; See a similar post from the original discussion for detailed expla=
nation
<br>&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/iso=
cpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onc=
lick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-p=
roposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups=
..google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" targ=
et=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/=
d/msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a>
<br>
<br>Using SFINAE to force users to explicitly move is a good approach, but =
I=20
<br>don&#39;t think it is always necessary. If my foo function is called, s=
ay,=20
<br>foo_move and is properly documented, there&#39;s no reason to force use=
rs to=20
<br>explicitly call std::move on their end. Especially, if the user is me,=
=20
<br>the implementer of foo_move.
<br></blockquote><div><br></div><div><br></div><div>OK, this + Thiago last =
comment opens an interesting topic.</div><div><br></div><div>Are there <i>a=
ny</i> interfaces, declared (semantically) as auto&amp;&amp; and NOT being =
a forwarding reference?=C2=A0</div><div><br></div><div>I am sure there isn&=
#39;t a single case in whole std, though I haven&#39;t verified that.=C2=A0=
</div><div><br></div><div>Further, will such an interface be good one. No, =
hell no.</div><div><br></div><div>If one takes an auto&amp;&amp; and does n=
ot forwards it - he loses opportunity, he essentially &quot;drops&quot; the=
 &quot;<span style=3D"display:inline!important;float:none;background-color:=
transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">forw=
arding reference</span>&quot;.</div><div>If one takes an auto&amp;&amp; and=
 moves it - he &quot;breaks&quot; the=C2=A0<span style=3D"display:inline!im=
portant;float:none;background-color:transparent;color:rgb(34,34,34);font-fa=
mily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">&quot;</span><span>forwarding reference</sp=
an><span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-w=
eight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px">&quot; b=
y casting it.</span></div><div><br></div><div><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">This might not be spelled out in the sta=
ndard, but that is de-facto the case - <span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">auto&amp;&amp; </span><i>IS A </i><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px">&quot;Forwarding refer=
ence&quot;</span>.=C2=A0</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">And it better be! Otherwise this =
will make C++ even harder to teach and reason about!</span></div><div><span=
 style=3D"display:inline!important;float:none;background-color:transparent;=
color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:40=
0;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px"><br></span></div=
><div><span style=3D"display:inline!important;float:none;background-color:t=
ransparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fon=
t-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><=
/span></div><div><span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant=
:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorati=
on:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">If one declares and interface of type&amp;&amp;, this means &quot;I w=
ill take your soo-to-die-object&quot;, hence I can do whatever I want.</spa=
n></div><div><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);=
text-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:nor=
mal;font-variant:normal;text-decoration:none;word-spacing:0px;display:inlin=
e!important;white-space:normal;float:none;background-color:transparent">How=
ever</span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);te=
xt-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norma=
l;font-variant:normal;text-decoration:none;word-spacing:0px;display:inline!=
important;white-space:normal;float:none;background-color:transparent"><br><=
/span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);text-tr=
ansform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;text-decoration:none;word-spacing:0px;display:inline!impor=
tant;white-space:normal;float:none;background-color:transparent">If one <sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">declares and i=
nterface of auto&amp;&amp;, this means &quot;I will accept what you give me=
&quot;, it does <i>not</i> mean, &quot;<span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">I will take your soo-to-die-of-any-type</span>&=
quot;,</span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"><span style=3D"display:inline!important;float:none;background-color:tra=
nsparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-=
weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px">hence <=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px">I can NOT do=
 whatever I want, otherwise <i>one is not keeping the promise of the interf=
ace</i></span>.</span></span></div><div><span style=3D"text-align:left;colo=
r:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;text-decoration:none;word-spacing:0=
px;display:inline!important;white-space:normal;float:none;background-color:=
transparent"><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"></span></div><div>I<span style=3D"display:inline!important;float:none;b=
ackground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quo=
t;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-v=
ariant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-de=
coration:none;text-indent:0px;text-transform:none;white-space:normal;word-s=
pacing:0px"> <i>promised, </i>I will <i>accept </i>everything<i>.=C2=A0</i>=
</span></div><div><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><i><br></i></span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px">If you pass me a reference to your object and I <i=
>pretend</i> this is=C2=A0<span style=3D"display:inline!important;float:non=
e;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text=
-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px">soo-to-die object, it turns out I was lying in the first pla=
ce -</span></span></div><div><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px">I don&#39;t care about <i>accepting</i> everything, I care only abou=
t what suits me!</span></span></div><div><span style=3D"display:inline!impo=
rtant;float:none;background-color:transparent;color:rgb(34,34,34);font-fami=
ly:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-s=
tyle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-=
align:left;text-decoration:none;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px"><i></i><i></i><i></i><i></i><i></i><b></b><i>=
</i><u></u><sub></sub><sup></sup><strike></strike><br></span></div><div><sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">In any case yo=
u are free to make foo_move - you have all the tools (and the reasons) in t=
he world to do so.</span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px"><br></span></div><div><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px">I am talking about the default correct =
behavior out of the box.</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">Unification of the syntax enforce=
s that correct behavior and makes lying harder.=C2=A0</span></div><div><spa=
n style=3D"display:inline!important;float:none;background-color:transparent=
;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:4=
00;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px"><br></span></di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>&gt; =C2=A0 =C2=A0 Forwarding and moving a value have a fundamental dif=
ference in
<br>&gt; =C2=A0 =C2=A0 strength.
<br>&gt; =C2=A0 =C2=A0 Forwarding does not move the value unless permitted =
by the program
<br>&gt; =C2=A0 =C2=A0 (i.e.
<br>&gt; =C2=A0 =C2=A0 the value is assumed to be unused afterwards) while =
std::move is
<br>&gt; =C2=A0 =C2=A0 stronger and will move even lvalue. The fact that bo=
th may end up
<br>&gt; =C2=A0 =C2=A0 moving
<br>&gt; =C2=A0 =C2=A0 the value does not mean they are the same and should=
 be expressed the
<br>&gt; =C2=A0 =C2=A0 same way. Being more explicit about the intent is be=
neficial to the
<br>&gt; =C2=A0 =C2=A0 developer, experienced or junior.
<br>&gt;=20
<br>&gt; Question is what is the original intend? And actually the intend i=
n both=20
<br>&gt; cases is to give the object away.
<br>
<br>That&#39;s from the function caller&#39;s perspective. And as far as th=
e caller=20
<br>is concerned, if you want to move, you use std::move. You never use=20
<br>std::forward to move a value.
<br>
<br>As a function implementer (or, more accurately, receiver of the functio=
n=20
<br>arguments), you can have different intentions wrt. the arguments. Some=
=20
<br>of the arguments you may move, others forward, thirds modify or copy. M=
y=20
<br>point is that the compiler is not able and should not be given liberty=
=20
<br>to decide which behavior to apply in each case. And the end code will=
=20
<br>have better quality if this intent is apparent.
<br>
<br>&gt; About the &quot;ugliness&quot;.
<br>&gt;=20
<br>&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but i=
t does clash=20
<br>&gt; with the binary operator &amp;&amp; and I see no way around that.
<br>&gt;=20
<br>&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a =
keyword val=20
<br>&gt; passin.
<br>
<br>These don&#39;t look any better to me, sorry. Ignoring for a moment tha=
t I=20
<br>don&#39;t like the idea to begin with, I would prefer a function-style=
=20
<br>keyword instead of new obscure operators, especially 3 or more=20
<br>characters long.=C2=A0<br></blockquote></div></blockquote></div></block=
quote></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/d689e667-19c2-4e32-be9f-5c040da3eab5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d689e667-19c2-4e32-be9f-5c040da3eab5=
%40isocpp.org</a>.<br />

------=_Part_61449_1255623196.1528459511636--

------=_Part_61448_699966038.1528459511635--

.


Author: florian.csdt@gmail.com
Date: Fri, 8 Jun 2018 05:26:02 -0700 (PDT)
Raw View
------=_Part_61959_1340363740.1528460763053
Content-Type: multipart/alternative;
 boundary="----=_Part_61960_1198602855.1528460763055"

------=_Part_61960_1198602855.1528460763055
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le vendredi 8 juin 2018 14:05:11 UTC+2, mihailn...@gmail.com a =C3=A9crit :
>
>
>
> On Friday, June 8, 2018 at 2:34:31 PM UTC+3, floria...@gmail.com wrote:
>>
>> Another way to see it is:
>>
>> Both when you forward and when you move, you promise you will not touch=
=20
>> the object again (except for rebinding it to another value).
>>
>
>
> In the case of forwarding reference you can't even rebind or at least you=
=20
> should not, much the same way you should not move a frw ref.=20
>

You cannot rebind a "forwarding" reference only because it might be const.
But if you can ensure somehow it is not const, why couldn't you rebind it?
=20

>
> =20
>
>> I think that's the key point of this proposal.
>>
>> I envision the following rules:
>> decltype(x) | decltype(x&&>)
>> ------------|----------------
>> T           | T&&
>> T&          | T&
>> T&&         | T&&
>> const T     | const T&& // implicitely convertible to const T&
>> const T&    | const T&
>> const T&&   | const T&&
>>
>> When x is an identifier, it will be equivalent to=20
>> std::forward<decltype(x)>(x), and also std::move(x) if in addition x is=
=20
>> not a ref.
>> Those are the most common cases.
>>
>> However, this new operator cannot move a ref like std::move does.
>>
>
>
>
> Currently the proposal moves in all cases *except* if the identifier is=
=20
> "forwarding reference". This is - forward *iff*  decltype(x) =3D=3D=20
> substitutedType&&
>

Forwarding references do not exist... Believing they do will bring troubles=
..
The only thing that exist is a (not so) special deduction rule.
But forwarding is still useful.

Here is a code example that works with forward, but will not work with your=
=20
operator as you define it because of thinking forwarding references exist:
template <class T>
struct Call {
  void operator(T&& val) const {
    // T is not a "forwarding reference"
    bar(std::forward<T>(val)); // this forward will be wrong with your=20
operator as you specified it
  }
};

template <class T>
void foo(T&& val) {
  // T here is a "forwarding reference", so no problem here
  Call<T>{}(std::forward<T>(val)); // this forward is fine
}

And yes, that kind of code is actually useful and used, to partially=20
specialize a function for instance.

=20

>
> This will make it behave the same way move and forward are used today.
>
> Yes there are cases of moving a mutating ref. Not just in swap
>
> void merge(forward_list&& __list)
> { merge(std::move(__list), std::less<_Tp>()); }
> void
> merge(forward_list& __list)
> { merge(std::move(__list)); }
>

This use case is flawed. As you said, the interface is lying. So I don't=20
expect your operator to move in the second case.
=20

>
>
> This should work as well under the unified syntax. It will move in *both*=
=20
> cases as __list is *not* substitutedType&&
>
>
The problem with moving lvalue references is that you do not own that=20
reference so you cannot/shouldn't give it away.
So unless you rebind it to something else afterwards, you shouldn't be able=
=20
to move it.

So I really would expect giving away an lvalue reference is still an lvalue=
=20
reference.


> =20
>
>> And they are cases when you really want to do that:
>> template <class T>
>> void swap(T& a, T& b) {
>>   // decltype(a   ) -> T&
>>   // decltype(a&&>) -> T&
>>   // decltype(std::move(a)) -> T&&
>>
>>   T c =3D std::move(a);
>>   a =3D std::move(b);
>>   c =3D std::move(c);
>> }
>> The swap function cannot be implemented using the "giving up" operator=
=20
>> (nor is it lying about its interface).
>> So there are some use-cases for std::move that are not covered by this=
=20
>> operator: keeping std::move is needed.
>>
>> This proposal is still interesting for the most common cases where you=
=20
>> don't move a reference but a local variable, and for all the forwarding.
>> But it should also account for the other not covered use-cases.
>>
>> Florian
>>
>>
>> Le vendredi 8 juin 2018 12:43:27 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>>
>>>
>>>
>>> On Friday, June 8, 2018 at 11:33:55 AM UTC+3, Andrey Semashev wrote:
>>>>
>>>> On 06/08/18 09:32, mihailn...@gmail.com wrote:=20
>>>> >=20
>>>> > If one writes a function where he moves instead of forwarding=20
>>>> >=20
>>>> >=20
>>>> >     template< typename T >=20
>>>> >     void foo(T&& value)=20
>>>> >     {=20
>>>> >       vec.push_back(std::move(value));=20
>>>> >     }=20
>>>> > **//___^=20
>>>> > That will be *The Wrong Thing* to do.=20
>>>>
>>>> There's nothing wrong with it, as long as you actually want to move.=
=20
>>>>
>>>> > This is because one /lies against the interface /- T&& is a=20
>>>> forwarding=20
>>>> > reference,/by definition/.=20
>>>> >=20
>>>> > Using "object passing", /prevents/ you to lie!=20
>>>>
>>>> There's no such thing as a forwarding reference in the language. Using=
=20
>>>> T&&, where T is a template argument, for forwarding is just one use=20
>>>> case, but there are also other. For example, this syntax can be used=
=20
>>>> for=20
>>>> generalization so that you don't have to write multiple overloads for=
=20
>>>> different argument types.=20
>>>>
>>>> > See a similar post from the original discussion for detailed=20
>>>> explanation=20
>>>> >=20
>>>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo=
/Gld277dtDQAJ=20
>>>>
>>>> Using SFINAE to force users to explicitly move is a good approach, but=
=20
>>>> I=20
>>>> don't think it is always necessary. If my foo function is called, say,=
=20
>>>> foo_move and is properly documented, there's no reason to force users=
=20
>>>> to=20
>>>> explicitly call std::move on their end. Especially, if the user is me,=
=20
>>>> the implementer of foo_move.=20
>>>>
>>>
>>>
>>> OK, this + Thiago last comment opens an interesting topic.
>>>
>>> Are there *any* interfaces, declared (semantically) as auto&& and NOT=
=20
>>> being a forwarding reference?=20
>>>
>>> I am sure there isn't a single case in whole std, though I haven't=20
>>> verified that.=20
>>>
>>> Further, will such an interface be good one. No, hell no.
>>>
>>> If one takes an auto&& and does not forwards it - he loses opportunity,=
=20
>>> he essentially "drops" the "forwarding reference".
>>> If one takes an auto&& and moves it - he "breaks" the "forwarding=20
>>> reference" by casting it.
>>>
>>> This might not be spelled out in the standard, but that is de-facto the=
=20
>>> case - auto&& *IS A *"Forwarding reference".=20
>>>
>>> And it better be! Otherwise this will make C++ even harder to teach and=
=20
>>> reason about!
>>>
>>>
>>> If one declares and interface of type&&, this means "I will take your=
=20
>>> soo-to-die-object", hence I can do whatever I want.
>>>
>>> However
>>>
>>> If one declares and interface of auto&&, this means "I will accept what=
=20
>>> you give me", it does *not* mean, "I will take your=20
>>> soo-to-die-of-any-type",
>>> hence I can NOT do whatever I want, otherwise *one is not keeping the=
=20
>>> promise of the interface*.
>>>
>>> I *promised, *I will *accept *everything*. *
>>>
>>> If you pass me a reference to your object and I *pretend* this is soo-t=
o-die=20
>>> object, it turns out I was lying in the first place -
>>> I don't care about *accepting* everything, I care only about what suits=
=20
>>> me!
>>>
>>> In any case you are free to make foo_move - you have all the tools (and=
=20
>>> the reasons) in the world to do so.
>>>
>>> I am talking about the default correct behavior out of the box.
>>>
>>> Unification of the syntax enforces that correct behavior and makes lyin=
g=20
>>> harder.=20
>>>
>>> =20
>>>
>>>>
>>>> >     Forwarding and moving a value have a fundamental difference in=
=20
>>>> >     strength.=20
>>>> >     Forwarding does not move the value unless permitted by the=20
>>>> program=20
>>>> >     (i.e.=20
>>>> >     the value is assumed to be unused afterwards) while std::move is=
=20
>>>> >     stronger and will move even lvalue. The fact that both may end u=
p=20
>>>> >     moving=20
>>>> >     the value does not mean they are the same and should be expresse=
d=20
>>>> the=20
>>>> >     same way. Being more explicit about the intent is beneficial to=
=20
>>>> the=20
>>>> >     developer, experienced or junior.=20
>>>> >=20
>>>> > Question is what is the original intend? And actually the intend in=
=20
>>>> both=20
>>>> > cases is to give the object away.=20
>>>>
>>>> That's from the function caller's perspective. And as far as the calle=
r=20
>>>> is concerned, if you want to move, you use std::move. You never use=20
>>>> std::forward to move a value.=20
>>>>
>>>> As a function implementer (or, more accurately, receiver of the=20
>>>> function=20
>>>> arguments), you can have different intentions wrt. the arguments. Some=
=20
>>>> of the arguments you may move, others forward, thirds modify or copy.=
=20
>>>> My=20
>>>> point is that the compiler is not able and should not be given liberty=
=20
>>>> to decide which behavior to apply in each case. And the end code will=
=20
>>>> have better quality if this intent is apparent.=20
>>>>
>>>> > About the "ugliness".=20
>>>> >=20
>>>> > Well, I really hoped a simple && would do the trick, but it does=20
>>>> clash=20
>>>> > with the binary operator && and I see no way around that.=20
>>>> >=20
>>>> > An alternative might be val~~ or val~&& or just val~ or a keyword va=
l=20
>>>> > passin.=20
>>>>
>>>> These don't look any better to me, sorry. Ignoring for a moment that I=
=20
>>>> don't like the idea to begin with, I would prefer a function-style=20
>>>> keyword instead of new obscure operators, especially 3 or more=20
>>>> characters long.=20
>>>>
>>>

--=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/a35c512e-fdff-40b8-b513-354990f34adb%40isocpp.or=
g.

------=_Part_61960_1198602855.1528460763055
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le vendredi 8 juin 2018 14:05:11 UTC+2, mihailn...=
@gmail.com a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 2:34:31 PM UTC+3, <a>fl=
oria...@gmail.com</a> wrote:<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">Another way to see it is:<br><br>Both when you forward and when y=
ou move, you promise you will not touch the object again (except for rebind=
ing it to another value).<br></div></blockquote><div><br></div><div><br></d=
iv><div>In the case of forwarding reference you can&#39;t even rebind or at=
 least you should not, much the same way you should not move a frw ref.=C2=
=A0</div></div></blockquote><div><br></div><div>You cannot rebind a &quot;f=
orwarding&quot; reference only because it might be const.</div><div>But if =
you can ensure somehow it is not const, why couldn&#39;t you rebind it?<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 di=
r=3D"ltr"><div><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-lef=
t:1ex"><div dir=3D"ltr">I think that&#39;s the key point of this proposal.<=
br><br>I envision the following rules:<br><span style=3D"font-family:courie=
r new,monospace">decltype(x) | decltype(x&amp;&amp;&gt;)<br>------------|--=
--------------<br>T=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 | T&amp;&amp;<br>T&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0 | T&amp;<br>T&amp;&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 | T&amp;&amp;<br>const T=C2=A0=C2=A0=C2=A0=C2=A0 | const T&amp;&amp;=
 // implicitely convertible to const T&amp;<br>const T&amp;=C2=A0=C2=A0=C2=
=A0 | const T&amp;<br>const T&amp;&amp;=C2=A0=C2=A0 | const T&amp;&amp;<br>=
</span><br>When <span style=3D"font-family:courier new,monospace">x</span> =
is an identifier, it will be equivalent to <span style=3D"font-family:couri=
er new,monospace">std::forward&lt;decltype(x)&gt;(x)</span>, and also <span=
 style=3D"font-family:courier new,monospace">std::move(x)</span> if in addi=
tion <span style=3D"font-family:courier new,monospace">x</span> is not a re=
f.<br>Those are the most common cases.<br><br>However, this new operator ca=
nnot move a ref like <span style=3D"font-family:courier new,monospace">std:=
:move</span> does.<br></div></blockquote><div><br></div><div><br></div><div=
><br></div><div>Currently the proposal moves in all cases <i>except</i> if =
the identifier is &quot;forwarding reference&quot;. This is - forward <b>if=
f</b>=C2=A0 <font face=3D"courier new,monospace"><span style=3D"text-align:=
left;color:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing=
:normal;font-size:13px;font-style:normal;font-variant:normal;font-weight:40=
0;text-decoration:none;word-spacing:0px;display:inline!important;white-spac=
e:normal;float:none;background-color:transparent">decltype(x) =3D=3D </span=
>substitutedType&amp;&amp;</font></div></div></blockquote><div><br></div><d=
iv>Forwarding references do not exist... Believing they do will bring troub=
les.</div><div>The only thing that exist is a (not so) special deduction ru=
le.</div><div>But forwarding is still useful.</div><div><br></div><div>Here=
 is a code example that works with forward, but will not work with your ope=
rator as you define it because of thinking forwarding references exist:</di=
v><div><div style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: br=
eak-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
emplate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> T</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: #008=
;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">Call</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">voi=
d</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> val</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: #008;" class=3D"style=
d-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </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 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// T is not a &quot;forwarding reference&quot;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 bar</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #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">forward</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>val</span><span style=3D"color: #660;" class=3D"styled-by-prettify">));</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #800;" class=3D"styled-by-prettify">// this forward will b=
e wrong with your operator as you specified it</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>=C2=A0 </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><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">template</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cla=
ss</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</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: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> val</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: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// T here is a =
&quot;forwarding reference&quot;, so no problem here</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Call</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;{}(</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-pret=
tify">forward</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">val</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">// this forward is fine</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span></div></code></div></div><div><=
br></div><div>And yes, that kind of code is actually useful and used, to pa=
rtially specialize a function for instance.<br><br></div><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><font fac=
e=3D"courier new,monospace"></font><br></div><div>This will make it behave =
the same way move and forward are used today.</div><div><br></div><div>Yes =
there are cases of moving a mutating ref. Not just in swap</div><font face=
=3D"courier new,monospace"><br> void merge(forward_list&amp;&amp; __list)<b=
r> { merge(std::move(__list), std::less&lt;_Tp&gt;()); }<br> void<br> merge=
(forward_list&amp; __list)<br></font><div><font face=3D"courier new,monospa=
ce"> { merge(std::move(__list)); }</font></div></div></blockquote><div><br>=
</div><div>This use case is flawed. As you said, the interface is lying. So=
 I don&#39;t expect your operator to move in the second case.<br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div><br></div><div><br></div><div>This should work as well under the unifi=
ed syntax. It will move in <i>both</i> cases as<font face=3D"courier new,mo=
nospace"> __list</font> is <b>not</b>=C2=A0<span style=3D"background-color:=
transparent;border-bottom-color:rgb(34,34,34);border-bottom-style:none;bord=
er-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-style:none;=
border-left-width:0px;border-right-color:rgb(34,34,34);border-right-style:n=
one;border-right-width:0px;border-top-color:rgb(34,34,34);border-top-style:=
none;border-top-width:0px;color:rgb(34,34,34);display:inline;float:none;fon=
t-family:courier new,monospace;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;margin-bottom:0px;margin-lef=
t:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;p=
adding-right:0px;padding-top:0px;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px"></span>=
<span style=3D"display:inline!important;float:none;background-color:transpa=
rent;color:rgb(34,34,34);font-family:courier new,monospace;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">substitutedType&amp;&amp;</span></div><d=
iv><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div></=
div></blockquote><div><br></div><div>The problem with moving lvalue referen=
ces is that you do not own that reference so you cannot/shouldn&#39;t give =
it away.</div><div>So unless you rebind it to something else afterwards, yo=
u shouldn&#39;t be able to move it.</div><div><br></div><div>So I really wo=
uld expect giving away an lvalue reference is still an lvalue reference.<br=
></div><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 di=
r=3D"ltr"><div></div><div><br></div><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr">And they are cases when you really want =
to do that:<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 sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</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"> swap</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">T</span><span style=3D"color:#660">&amp;</span><span s=
tyle=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</span><span style=
=3D"color:#000"> b</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color=
:#000"><br>=C2=A0 </span><span style=3D"color:#800">// decltype(a =C2=A0 ) =
-&gt; T&amp;</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=
=3D"color:#800">// decltype(a&amp;&amp;&gt;) -&gt; T&amp;</span><span style=
=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#800">// decltype(st=
d::move(a)) -&gt; T&amp;&amp;</span><span style=3D"color:#000"><br><br>=C2=
=A0 T c </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#00=
0">move</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>a</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br=
>=C2=A0 a </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">move</span><span style=3D"color:#660">(</span><span style=3D"color:#00=
0">b</span><span style=3D"color:#660">);</span><span style=3D"color:#000"><=
br>=C2=A0 c </span><span style=3D"color:#660">=3D</span><span style=3D"colo=
r:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"color=
:#000">move</span><span style=3D"color:#660">(</span><span style=3D"color:#=
000">c</span><span style=3D"color:#660">);</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><=
br></span></div></code></div>The swap function cannot be implemented using =
the &quot;giving up&quot; operator (nor is it lying about its interface).<b=
r>So there are some use-cases for <span style=3D"font-family:courier new,mo=
nospace">std::move</span> that are not covered by this operator: keeping <s=
pan style=3D"font-family:courier new,monospace">std::move</span> is needed.=
<br><br>This proposal is still interesting for the most common cases where =
you don&#39;t move a reference but a local variable, and for all the forwar=
ding.<br>But it should also account for the other not covered use-cases.<br=
><br>Florian<br><br><br>Le vendredi 8 juin 2018 12:43:27 UTC+2, <a>mihailn.=
...@gmail.com</a> a =C3=A9crit=C2=A0:<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"><br><br>On Friday, June 8, 2018 at 11:33:55 AM UTC+3, And=
rey Semashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On 06/08/18 09:3=
2, <a rel=3D"nofollow">mihailn...@gmail.com</a> wrote:
<br>&gt;=20
<br>&gt; If one writes a function where he moves instead of forwarding
<br>&gt;=20
<br>&gt;=20
<br>&gt; =C2=A0=C2=A0=C2=A0=C2=A0template&lt; typename T &gt;
<br>&gt; =C2=A0=C2=A0 =C2=A0void foo(T&amp;&amp; value)
<br>&gt; =C2=A0=C2=A0 =C2=A0{
<br>&gt; =C2=A0=C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));
<br>&gt; =C2=A0=C2=A0 =C2=A0}
<br>&gt; **//___^
<br>&gt; That will be *The Wrong Thing* to do.
<br>
<br>There&#39;s nothing wrong with it, as long as you actually want to move=
..
<br>
<br>&gt; This is because one /lies against the interface /- T&amp;&amp; is =
a forwarding=20
<br>&gt; reference,/by definition/.
<br>&gt;=20
<br>&gt; Using &quot;object passing&quot;, /prevents/ you to lie!
<br>
<br>There&#39;s no such thing as a forwarding reference in the language. Us=
ing=20
<br>T&amp;&amp;, where T is a template argument, for forwarding is just one=
 use=20
<br>case, but there are also other. For example, this syntax can be used fo=
r=20
<br>generalization so that you don&#39;t have to write multiple overloads f=
or=20
<br>different argument types.
<br>
<br>&gt; See a similar post from the original discussion for detailed expla=
nation
<br>&gt; <a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-propos=
als/Kdt1dVwL7bo/Gld277dtDQAJ" rel=3D"nofollow" target=3D"_blank" onmousedow=
n=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-prop=
osals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=3D"this.href=3D&#=
39;https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/G=
ld277dtDQAJ&#39;;return true;">https://groups.google.com/a/<wbr>isocpp.org/=
d/msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a>
<br>
<br>Using SFINAE to force users to explicitly move is a good approach, but =
I=20
<br>don&#39;t think it is always necessary. If my foo function is called, s=
ay,=20
<br>foo_move and is properly documented, there&#39;s no reason to force use=
rs to=20
<br>explicitly call std::move on their end. Especially, if the user is me,=
=20
<br>the implementer of foo_move.
<br></blockquote><div><br></div><div><br></div><div>OK, this + Thiago last =
comment opens an interesting topic.</div><div><br></div><div>Are there <i>a=
ny</i> interfaces, declared (semantically) as auto&amp;&amp; and NOT being =
a forwarding reference?=C2=A0</div><div><br></div><div>I am sure there isn&=
#39;t a single case in whole std, though I haven&#39;t verified that.=C2=A0=
</div><div><br></div><div>Further, will such an interface be good one. No, =
hell no.</div><div><br></div><div>If one takes an auto&amp;&amp; and does n=
ot forwards it - he loses opportunity, he essentially &quot;drops&quot; the=
 &quot;<span style=3D"display:inline!important;float:none;background-color:=
transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">forw=
arding reference</span>&quot;.</div><div>If one takes an auto&amp;&amp; and=
 moves it - he &quot;breaks&quot; the=C2=A0<span style=3D"display:inline!im=
portant;float:none;background-color:transparent;color:rgb(34,34,34);font-fa=
mily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font=
-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;tex=
t-align:left;text-decoration:none;text-indent:0px;text-transform:none;white=
-space:normal;word-spacing:0px">&quot;</span><span>forwarding reference</sp=
an><span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-w=
eight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px">&quot; b=
y casting it.</span></div><div><br></div><div><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">This might not be spelled out in the sta=
ndard, but that is de-facto the case - <span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">auto&amp;&amp; </span><i>IS A </i><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px">&quot;Forwarding refer=
ence&quot;</span>.=C2=A0</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">And it better be! Otherwise this =
will make C++ even harder to teach and reason about!</span></div><div><span=
 style=3D"display:inline!important;float:none;background-color:transparent;=
color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:40=
0;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px"><br></span></div=
><div><span style=3D"display:inline!important;float:none;background-color:t=
ransparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fon=
t-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><=
/span></div><div><span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant=
:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorati=
on:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">If one declares and interface of type&amp;&amp;, this means &quot;I w=
ill take your soo-to-die-object&quot;, hence I can do whatever I want.</spa=
n></div><div><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);=
text-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:nor=
mal;font-variant:normal;text-decoration:none;word-spacing:0px;display:inlin=
e!important;white-space:normal;float:none;background-color:transparent">How=
ever</span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);te=
xt-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norma=
l;font-variant:normal;text-decoration:none;word-spacing:0px;display:inline!=
important;white-space:normal;float:none;background-color:transparent"><br><=
/span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);text-tr=
ansform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;text-decoration:none;word-spacing:0px;display:inline!impor=
tant;white-space:normal;float:none;background-color:transparent">If one <sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">declares and i=
nterface of auto&amp;&amp;, this means &quot;I will accept what you give me=
&quot;, it does <i>not</i> mean, &quot;<span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">I will take your soo-to-die-of-any-type</span>&=
quot;,</span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"><span style=3D"display:inline!important;float:none;background-color:tra=
nsparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-=
weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px">hence <=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px">I can NOT do=
 whatever I want, otherwise <i>one is not keeping the promise of the interf=
ace</i></span>.</span></span></div><div><span style=3D"text-align:left;colo=
r:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;text-decoration:none;word-spacing:0=
px;display:inline!important;white-space:normal;float:none;background-color:=
transparent"><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><br></span></span></div><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;text-decoration:none;word-spacing:0px;displa=
y:inline!important;white-space:normal;float:none;background-color:transpare=
nt"></span></div><div>I<span style=3D"display:inline!important;float:none;b=
ackground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quo=
t;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-v=
ariant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-de=
coration:none;text-indent:0px;text-transform:none;white-space:normal;word-s=
pacing:0px"> <i>promised, </i>I will <i>accept </i>everything<i>.=C2=A0</i>=
</span></div><div><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><i><br></i></span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px">If you pass me a reference to your object and I <i=
>pretend</i> this is=C2=A0<span style=3D"display:inline!important;float:non=
e;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text=
-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px">soo-to-die object, it turns out I was lying in the first pla=
ce -</span></span></div><div><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px">I don&#39;t care about <i>accepting</i> everything, I care only abou=
t what suits me!</span></span></div><div><span style=3D"display:inline!impo=
rtant;float:none;background-color:transparent;color:rgb(34,34,34);font-fami=
ly:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-s=
tyle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-=
align:left;text-decoration:none;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px"><i></i><i></i><i></i><i></i><i></i><b></b><i>=
</i><u></u><sub></sub><sup></sup><strike></strike><br></span></div><div><sp=
an style=3D"display:inline!important;float:none;background-color:transparen=
t;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px">In any case yo=
u are free to make foo_move - you have all the tools (and the reasons) in t=
he world to do so.</span></div><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px"><br></span></div><div><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px">I am talking about the default correct =
behavior out of the box.</span></div><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><br></span></div><div><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px">Unification of the syntax enforce=
s that correct behavior and makes lying harder.=C2=A0</span></div><div><spa=
n style=3D"display:inline!important;float:none;background-color:transparent=
;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:4=
00;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px"><br></span></di=
v><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>&gt; =C2=A0 =C2=A0 Forwarding and moving a value have a fundamental dif=
ference in
<br>&gt; =C2=A0 =C2=A0 strength.
<br>&gt; =C2=A0 =C2=A0 Forwarding does not move the value unless permitted =
by the program
<br>&gt; =C2=A0 =C2=A0 (i.e.
<br>&gt; =C2=A0 =C2=A0 the value is assumed to be unused afterwards) while =
std::move is
<br>&gt; =C2=A0 =C2=A0 stronger and will move even lvalue. The fact that bo=
th may end up
<br>&gt; =C2=A0 =C2=A0 moving
<br>&gt; =C2=A0 =C2=A0 the value does not mean they are the same and should=
 be expressed the
<br>&gt; =C2=A0 =C2=A0 same way. Being more explicit about the intent is be=
neficial to the
<br>&gt; =C2=A0 =C2=A0 developer, experienced or junior.
<br>&gt;=20
<br>&gt; Question is what is the original intend? And actually the intend i=
n both=20
<br>&gt; cases is to give the object away.
<br>
<br>That&#39;s from the function caller&#39;s perspective. And as far as th=
e caller=20
<br>is concerned, if you want to move, you use std::move. You never use=20
<br>std::forward to move a value.
<br>
<br>As a function implementer (or, more accurately, receiver of the functio=
n=20
<br>arguments), you can have different intentions wrt. the arguments. Some=
=20
<br>of the arguments you may move, others forward, thirds modify or copy. M=
y=20
<br>point is that the compiler is not able and should not be given liberty=
=20
<br>to decide which behavior to apply in each case. And the end code will=
=20
<br>have better quality if this intent is apparent.
<br>
<br>&gt; About the &quot;ugliness&quot;.
<br>&gt;=20
<br>&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but i=
t does clash=20
<br>&gt; with the binary operator &amp;&amp; and I see no way around that.
<br>&gt;=20
<br>&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a =
keyword val=20
<br>&gt; passin.
<br>
<br>These don&#39;t look any better to me, sorry. Ignoring for a moment tha=
t I=20
<br>don&#39;t like the idea to begin with, I would prefer a function-style=
=20
<br>keyword instead of new obscure operators, especially 3 or more=20
<br>characters long.=C2=A0<br></blockquote></div></blockquote></div></block=
quote></div></blockquote></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/a35c512e-fdff-40b8-b513-354990f34adb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a35c512e-fdff-40b8-b513-354990f34adb=
%40isocpp.org</a>.<br />

------=_Part_61960_1198602855.1528460763055--

------=_Part_61959_1340363740.1528460763053--

.


Author: mihailnajdenov@gmail.com
Date: Fri, 8 Jun 2018 07:35:52 -0700 (PDT)
Raw View
------=_Part_59624_824155362.1528468552861
Content-Type: multipart/alternative;
 boundary="----=_Part_59625_1094955649.1528468552862"

------=_Part_59625_1094955649.1528468552862
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Friday, June 8, 2018 at 3:26:03 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le vendredi 8 juin 2018 14:05:11 UTC+2, mihailn...@gmail.com a =C3=A9crit=
 :
>>
>>
>>
>> On Friday, June 8, 2018 at 2:34:31 PM UTC+3, floria...@gmail.com wrote:
>>>
>>> Another way to see it is:
>>>
>>> Both when you forward and when you move, you promise you will not touch=
=20
>>> the object again (except for rebinding it to another value).
>>>
>>
>>
>> In the case of forwarding reference you can't even rebind or at least yo=
u=20
>> should not, much the same way you should not move a frw ref.=20
>>
>
> You cannot rebind a "forwarding" reference only because it might be const=
..
> But if you can ensure somehow it is not const, why couldn't you rebind it=
?=20
>


Because it will not "rebind", but override the result of the operation you =
forwarded=20
to.

auto ingr =3D "apple";
make_cacke(ingr);
// use what's left from apple... or not

auto make_cacke(auto&& ingr)
{
  auto fill =3D make_filling_from_half_apple(ingr&&>);

  ingr =3D "orange";=20

  return make_cake(fill&&>, make_blat(ingr&&>));
}

=20

>
>> =20
>>
>>> I think that's the key point of this proposal.
>>>
>>> I envision the following rules:
>>> decltype(x) | decltype(x&&>)
>>> ------------|----------------
>>> T           | T&&
>>> T&          | T&
>>> T&&         | T&&
>>> const T     | const T&& // implicitely convertible to const T&
>>> const T&    | const T&
>>> const T&&   | const T&&
>>>
>>> When x is an identifier, it will be equivalent to=20
>>> std::forward<decltype(x)>(x), and also std::move(x) if in addition x is=
=20
>>> not a ref.
>>> Those are the most common cases.
>>>
>>> However, this new operator cannot move a ref like std::move does.
>>>
>>
>>
>>
>> Currently the proposal moves in all cases *except* if the identifier is=
=20
>> "forwarding reference". This is - forward *iff*  decltype(x) =3D=3D=20
>> substitutedType&&
>>
>
> Forwarding references do not exist... Believing they do will bring=20
> troubles.
>


I think it is better for the C++ language to believe and advertise Forwardi=
ng=20
references.

The deduction rules should be implementation detail.

This makes the language easier to both teach and use


=20

> The only thing that exist is a (not so) special deduction rule.
> But forwarding is still useful.
>
> Here is a code example that works with forward, but will not work with=20
> your operator as you define it because of thinking forwarding references=
=20
> exist:
> template <class T>
> struct Call {
>   void operator(T&& val) const {
>     // T is not a "forwarding reference"
>     bar(std::forward<T>(val)); // this forward will be wrong with your=20
> operator as you specified it
>   }
> };
>
> template <class T>
> void foo(T&& val) {
>   // T here is a "forwarding reference", so no problem here
>   Call<T>{}(std::forward<T>(val)); // this forward is fine
> }
>
> And yes, that kind of code is actually useful and used, to partially=20
> specialize a function for instance.
>


Great, great example.=20

On one hand this case I believe *could* be handled as well  - after all you=
=20
are *still* initializing operator()(T&&) with an "odd" type like operator()=
(const=20
somthing& && )

On the other, *should* it be handled?
It is easier to reason about the code so that operator(T&&) is accepting an=
=20
rvalue, and then NOT use &&> so that the code stands out when forward<T> is=
=20
used.=20

Or it might be "nice" to handle this as well?=20

Definitely an open question. Opinions (and expertise) are welcome.

Great example anyway. I will dedicate it a chapter in the next draft.

=20

>
> =20
>
>>
>> This will make it behave the same way move and forward are used today.
>>
>> Yes there are cases of moving a mutating ref. Not just in swap
>>
>> void merge(forward_list&& __list)
>> { merge(std::move(__list), std::less<_Tp>()); }
>> void
>> merge(forward_list& __list)
>> { merge(std::move(__list)); }
>>
>
> This use case is flawed. As you said, the interface is lying. So I don't=
=20
> expect your operator to move in the second case.
>


Not that much flowed - its a copy and paste from GCC impl of forward_list.h=
=20
:)

In any case, here it is fine because the function is called "merge" - it=20
implies the argument is "merged into" the destination and no longer exists

=20

> =20
>
>>
>>
>> This should work as well under the unified syntax. It will move in *both=
*=20
>> cases as __list is *not* substitutedType&&
>>
>>
> The problem with moving lvalue references is that you do not own that=20
> reference so you cannot/shouldn't give it away.
> So unless you rebind it to something else afterwards, you shouldn't be=20
> able to move it.
>
> So I really would expect giving away an lvalue reference is still an=20
> lvalue reference.
>


I see, well its a different approach, as said I wish this operator to be=20
direct, drop-in replacement for move and forward so it should behave like=
=20
them as much as possible.
I don't want to change the rules, just to have right-by-default language=20
construct.=20



> =E2=80=A6..
>>
>

--=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/ee21d1f8-2d87-414f-96f5-468e280eb505%40isocpp.or=
g.

------=_Part_59625_1094955649.1528468552862
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 3:26:03 PM UTC+3, flori=
a...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><br><br>Le vendredi 8 juin 2018 14:05:11 UTC+2, <a>mihailn...@gmai=
l.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"ltr"><br><br>On Friday, June 8, 2018 at 2:34:31 PM UTC+3, <a>floria..=
..@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">Another way to see it is:<br><br>Both when you forward and when you mov=
e, you promise you will not touch the object again (except for rebinding it=
 to another value).<br></div></blockquote><div><br></div><div><br></div><di=
v>In the case of forwarding reference you can&#39;t even rebind or at least=
 you should not, much the same way you should not move a frw ref.=C2=A0</di=
v></div></blockquote><div><br></div><div>You cannot rebind a &quot;forwardi=
ng&quot; reference only because it might be const.</div><div>But if you can=
 ensure somehow it is not const, why couldn&#39;t you rebind it?=C2=A0</div=
></div></blockquote><div><br></div><div><br></div><div>Because it will not =
&quot;rebind&quot;, but override the result of the operation you <span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;">forwarded to</spa=
n>.</div><div><font face=3D"courier new,monospace"></font><br></div><div><d=
iv style=3D"background-color: transparent; border-bottom-color: rgb(34, 34,=
 34); border-bottom-style: none; border-bottom-width: 0px; border-image-out=
set: 0; border-image-repeat: stretch; border-image-slice: 100%; border-imag=
e-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); =
border-left-style: none; border-left-width: 0px; border-right-color: rgb(34=
, 34, 34); border-right-style: none; border-right-width: 0px; border-top-co=
lor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color:=
 rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetic=
a&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font f=
ace=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34)=
; border-bottom-style: none; border-bottom-width: 0px; border-image-outset:=
 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-so=
urce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bord=
er-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34=
, 34); border-right-style: none; border-right-width: 0px; border-top-color:=
 rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bot=
tom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">auto in=
gr =3D &quot;apple&quot;;</font></div><div style=3D"background-color: trans=
parent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bo=
rder-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretc=
h; border-image-slice: 100%; border-image-source: none; border-image-width:=
 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-lef=
t-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none=
; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-st=
yle: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp=
;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: =
13px; font-style: normal; font-variant: normal; font-weight: 400; letter-sp=
acing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-r=
ight: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-=
indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-sp=
ace: normal; word-spacing: 0px;"><span style=3D"background-color: transpare=
nt; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; floa=
t: none; font-family: courier new,monospace; font-size: 13px; font-style: n=
ormal; font-variant: normal; font-weight: 400; letter-spacing: normal; marg=
in-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orpha=
ns: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-=
top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;">make_cacke</span><font face=3D"courier new,monospace" style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;">(<span style=3D"display: inline !important=
; float: none; background-color: transparent; color: rgb(34, 34, 34); font-=
family: courier new,monospace; font-size: 13px; font-style: normal; font-va=
riant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">in=
gr</span>);</font></div><div style=3D"background-color: transparent; border=
-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-wi=
dth: 0px; border-image-outset: 0; border-image-repeat: stretch; border-imag=
e-slice: 100%; border-image-source: none; border-image-width: 1; border-lef=
t-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; =
border-right-color: rgb(34, 34, 34); border-right-style: none; border-right=
-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bor=
der-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&am=
p;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-sty=
le: normal; font-variant: normal; font-weight: 400; letter-spacing: normal;=
 margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; =
orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pad=
ding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; t=
ext-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; w=
ord-spacing: 0px;"><font face=3D"courier new,monospace" style=3D"border-bot=
tom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width:=
 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-sl=
ice: 100%; border-image-source: none; border-image-width: 1; border-left-co=
lor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bord=
er-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wid=
th: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-=
top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ma=
rgin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; =
padding-top: 0px;">// use what&#39;s left from apple... or not</font></div>=
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><div>=
<font face=3D"courier new,monospace">auto <span style=3D"display: inline !i=
mportant; float: none; background-color: transparent; color: rgb(34, 34, 34=
); font-family: courier new,monospace; font-size: 13px; font-style: normal;=
 font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;">make_cacke</span>(auto&amp;&amp; <span style=3D"display: inline !impo=
rtant; float: none; background-color: transparent; color: rgb(34, 34, 34); =
font-family: courier new,monospace; font-size: 13px; font-style: normal; fo=
nt-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; t=
ext-align: left; text-decoration: none; text-indent: 0px; text-transform: n=
one; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px=
;">ingr</span>)</font></div><div><font face=3D"courier new,monospace">{</fo=
nt></div><div><font face=3D"courier new,monospace">=C2=A0 auto fill =3D mak=
e_filling_from_half_apple(<span style=3D"display: inline !important; float:=
 none; background-color: transparent; color: rgb(34, 34, 34); font-family: =
courier new,monospace; font-size: 13px; font-style: normal; font-variant: n=
ormal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">ingr</span=
>&amp;&amp;&gt;);</font><br></div><div><font face=3D"courier new,monospace"=
></font><br></div><div><font face=3D"courier new,monospace">=C2=A0 <span st=
yle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); display: inline; float: none; font-family: courier new,monospa=
ce; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decorati=
on: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width=
: 0px; white-space: normal; word-spacing: 0px;">ingr </span>=3D &quot;orang=
e&quot;;=C2=A0</font></div><div><font face=3D"courier new,monospace"><br></=
font></div><div><font face=3D"courier new,monospace">=C2=A0 return make_cak=
e(fill&amp;&amp;&gt;, make_blat(ingr&amp;&amp;&gt;));</font></div><div><fon=
t face=3D"courier new,monospace">}</font></div><div><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"><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><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">I think that&=
#39;s the key point of this proposal.<br><br>I envision the following rules=
:<br><span style=3D"font-family:courier new,monospace">decltype(x) | declty=
pe(x&amp;&amp;&gt;)<br>------------|----------------<br>T=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>T&amp;=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;<br>T&amp;&amp;=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>const T=C2=A0=
=C2=A0=C2=A0=C2=A0 | const T&amp;&amp; // implicitely convertible to const =
T&amp;<br>const T&amp;=C2=A0=C2=A0=C2=A0 | const T&amp;<br>const T&amp;&amp=
;=C2=A0=C2=A0 | const T&amp;&amp;<br></span><br>When <span style=3D"font-fa=
mily:courier new,monospace">x</span> is an identifier, it will be equivalen=
t to <span style=3D"font-family:courier new,monospace">std::forward&lt;decl=
type(x)&gt;(x)</span>, and also <span style=3D"font-family:courier new,mono=
space">std::move(x)</span> if in addition <span style=3D"font-family:courie=
r new,monospace">x</span> is not a ref.<br>Those are the most common cases.=
<br><br>However, this new operator cannot move a ref like <span style=3D"fo=
nt-family:courier new,monospace">std::move</span> does.<br></div></blockquo=
te><div><br></div><div><br></div><div><br></div><div>Currently the proposal=
 moves in all cases <i>except</i> if the identifier is &quot;forwarding ref=
erence&quot;. This is - forward <b>iff</b>=C2=A0 <font face=3D"courier new,=
monospace"><span style=3D"text-align:left;color:rgb(34,34,34);text-transfor=
m:none;text-indent:0px;letter-spacing:normal;font-size:13px;font-style:norm=
al;font-variant:normal;font-weight:400;text-decoration:none;word-spacing:0p=
x;display:inline!important;white-space:normal;float:none;background-color:t=
ransparent">decltype(x) =3D=3D </span>substitutedType&amp;&amp;</font></div=
></div></blockquote><div><br></div><div>Forwarding references do not exist.=
... Believing they do will bring troubles.</div></div></blockquote><div><br>=
</div><div><br></div><div>I think it is better for the C++ language to beli=
eve and advertise=C2=A0<span style=3D"display: inline !important; float: no=
ne; background-color: transparent; color: rgb(34, 34, 34); font-family: &qu=
ot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-styl=
e: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; =
orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text=
-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word=
-spacing: 0px;">Forwarding references.</span></div><div><span style=3D"disp=
lay: inline !important; float: none; background-color: transparent; color: =
rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-=
serif; font-size: 13px; font-style: normal; font-variant: normal; font-weig=
ht: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decorat=
ion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-widt=
h: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div><spa=
n style=3D"display: inline !important; float: none; background-color: trans=
parent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: no=
rmal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: lef=
t; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-t=
ext-stroke-width: 0px; white-space: normal; word-spacing: 0px;">The deducti=
on rules should be implementation detail.</span></div><div><span style=3D"d=
isplay: inline !important; float: none; background-color: transparent; colo=
r: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">This mak=
es the language easier to both teach and use</span></div><div><span style=
=3D"display: inline !important; float: none; background-color: transparent;=
 color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; f=
ont-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text=
-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-str=
oke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><=
div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><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"lt=
r"><div>The only thing that exist is a (not so) special deduction rule.</di=
v><div>But forwarding is still useful.</div><div><br></div><div>Here is a c=
ode example that works with forward, but will not work with your operator a=
s you define it because of thinking forwarding references exist:</div><div>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px"><code><div><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">&lt;</span><span style=3D"color:#008">class</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">struct</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#606">Call</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000=
"><br>=C2=A0 </span><span style=3D"color:#008">void</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">operator</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">T</span><span style=3D"color=
:#660">&amp;&amp;</span><span style=3D"color:#000"> val</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">const</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span=
 style=3D"color:#800">// T is not a &quot;forwarding reference&quot;</span>=
<span style=3D"color:#000"><br>=C2=A0 =C2=A0 bar</span><span style=3D"color=
:#660">(</span><span style=3D"color:#000">std</span><span style=3D"color:#6=
60">::</span><span style=3D"color:#000">forward</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#6=
60">&gt;(</span><span style=3D"color:#000">val</span><span style=3D"color:#=
660">));</span><span style=3D"color:#000"> </span><span style=3D"color:#800=
">// this forward will be wrong with your operator as you specified it</spa=
n><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">};<=
/span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">=
template</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#0=
00"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">void</span><span style=3D"color:#0=
00"> foo</span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">T</span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:=
#000"> val</span><span style=3D"color:#660">)</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><=
br>=C2=A0 </span><span style=3D"color:#800">// T here is a &quot;forwarding=
 reference&quot;, so no problem here</span><span style=3D"color:#000"><br>=
=C2=A0 </span><span style=3D"color:#606">Call</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660=
">&gt;{}(</span><span style=3D"color:#000">std</span><span style=3D"color:#=
660">::</span><span style=3D"color:#000">forward</span><span style=3D"color=
:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#=
660">&gt;(</span><span style=3D"color:#000">val</span><span style=3D"color:=
#660">)<wbr>);</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#800">// this forward is fine</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><=
/div></code></div></div><div><br></div><div>And yes, that kind of code is a=
ctually useful and used, to partially specialize a function for instance.<b=
r></div></div></blockquote><div><br></div><div><br></div><div>Great, great =
example.=C2=A0</div><div><br></div><div>On one hand this case I believe <i>=
could</i> be handled as well=C2=A0 - after all you are <i>still</i> initial=
izing <font face=3D"courier new,monospace">operator()(T&amp;&amp;)</font> w=
ith an &quot;odd&quot; type like <font face=3D"courier new,monospace">opera=
tor()(const somthing&amp; &amp;&amp; )</font></div><div><font face=3D"couri=
er new,monospace"></font><br></div><div>On the other, <i>should</i> it be h=
andled?<br></div><div>It is easier to reason about the code so that <font f=
ace=3D"courier new,monospace">operator(T&amp;&amp;</font>) is accepting an =
rvalue, and then NOT use &amp;&amp;&gt; so that the code stands out when <f=
ont face=3D"courier new,monospace">forward&lt;T&gt;</font> is used.=C2=A0</=
div><div><br></div><div>Or it might be &quot;nice&quot; to handle this as w=
ell?=C2=A0<br></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike=
></strike><br></div><div>Definitely an open question. Opinions (and experti=
se) are welcome.</div><div><br></div><div>Great example anyway. I will dedi=
cate it a chapter in the next draft.</div><div><br></div><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div=
><div>=C2=A0</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><font face=3D"courier new,monospace"></font><br></div><div>This will m=
ake it behave the same way move and forward are used today.</div><div><br><=
/div><div>Yes there are cases of moving a mutating ref. Not just in swap</d=
iv><font face=3D"courier new,monospace"><br> void merge(forward_list&amp;&a=
mp; __list)<br> { merge(std::move(__list), std::less&lt;_Tp&gt;()); }<br> v=
oid<br> merge(forward_list&amp; __list)<br></font><div><font face=3D"courie=
r new,monospace"> { merge(std::move(__list)); }</font></div></div></blockqu=
ote><div><br></div><div>This use case is flawed. As you said, the interface=
 is lying. So I don&#39;t expect your operator to move in the second case.<=
br></div></div></blockquote><div><br></div><div><br></div><div>Not that muc=
h flowed - its a copy and paste from GCC impl of <font face=3D"courier new,=
monospace">forward_list.h </font><font face=3D"arial,sans-serif">:)</font><=
/div><div><font face=3D"courier new,monospace"></font><font face=3D"arial,s=
ans-serif"></font><br></div><div>In any case, here it is fine because the f=
unction is called &quot;merge&quot; - it implies the argument is &quot;merg=
ed into&quot; the destination and no longer exists</div><div><br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div></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><br></div><div><br></div><div>This should work as well under=
 the unified syntax. It will move in <i>both</i> cases as<font face=3D"cour=
ier new,monospace"> __list</font> is <b>not</b>=C2=A0<span style=3D"backgro=
und-color:transparent;border-bottom-color:rgb(34,34,34);border-bottom-style=
:none;border-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-s=
tyle:none;border-left-width:0px;border-right-color:rgb(34,34,34);border-rig=
ht-style:none;border-right-width:0px;border-top-color:rgb(34,34,34);border-=
top-style:none;border-top-width:0px;color:rgb(34,34,34);display:inline;floa=
t:none;font-family:courier new,monospace;font-size:13px;font-style:normal;f=
ont-variant:normal;font-weight:400;letter-spacing:normal;margin-bottom:0px;=
margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-=
left:0px;padding-right:0px;padding-top:0px;text-align:left;text-decoration:=
none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x"></span><span style=3D"display:inline!important;float:none;background-col=
or:transparent;color:rgb(34,34,34);font-family:courier new,monospace;font-s=
ize:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spaci=
ng:normal;text-align:left;text-decoration:none;text-indent:0px;text-transfo=
rm:none;white-space:normal;word-spacing:0px">substitutedType&amp;&amp;</spa=
n></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><b=
r></div></div></blockquote><div><br></div><div>The problem with moving lval=
ue references is that you do not own that reference so you cannot/shouldn&#=
39;t give it away.</div><div>So unless you rebind it to something else afte=
rwards, you shouldn&#39;t be able to move it.</div><div><br></div><div>So I=
 really would expect giving away an lvalue reference is still an lvalue ref=
erence.<br></div></div></blockquote><div><br></div><div><br></div><div>I se=
e, well its a different approach, as said I wish this operator to be direct=
, drop-in replacement for move and forward so it should behave like them as=
 much as possible.</div><div>I don&#39;t want to change the rules, just to =
have right-by-default language construct.=C2=A0</div><div><br></div><div><b=
r></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> <br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div></div><div>=E2=80=A6..<br></div></div></blockquote></div></blockqu=
ote></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/ee21d1f8-2d87-414f-96f5-468e280eb505%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ee21d1f8-2d87-414f-96f5-468e280eb505=
%40isocpp.org</a>.<br />

------=_Part_59625_1094955649.1528468552862--

------=_Part_59624_824155362.1528468552861--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Fri, 8 Jun 2018 15:58:13 +0100
Raw View
--000000000000bd273d056e22a15d
Content-Type: text/plain; charset="UTF-8"

*What's the motivation?*

typing std::forward<decltype(x)>(x) is tiresome. The only way to make it
prettier, shorter and more expressive is to use a preprocessor macro, than
that sucks big time.

*Why doesn't std::forward(x) work?*

Because when x is an r-value reference, decltype(x) is not the same as the
type yielded by uttering the name of x.

*When do we need to forward objects?*

When using possibly-rvalue arguments that have been supplied to the current
function *and* we wish to use the possible rvalue unmolested.

*Any other times?*

Nope!

*What if we had a type that allowed x to be the same type as decltype(x) in
all cases?*

*Would it break any existing code?*

No

*Would it need a new keyword?*

No

*Or a new operator?*

No

*Example:*

template<class T> auto foo(T&&& x);

x is either an l-value reference or an r-value reference. Crucially, using
the name `x` will yield the same type.

*Thus forwarding becomes automatic, trivial and fully specified in its
declaration:*

template<class T> auto foo(T&&& x)
{
  return bar(x);  // x is implicitly forwarded
}

This cannot break code because there is no such thing as a reference to an
r-value reference or an rvalue-ref to an lvalue-ref.

*Possible complaint:*

*The interface leaks an implementation decision.*

In which case we could allow the following interface/implementation pair:

template<class T> auto foo(T&& x) -> int;
template<class T> auto foo(T&&& x) -> int
{
  // ...
}

And if we're going to do that, we could allow another non-keyword
annotation al-la override:

template<class T> auto foo(T&& x) -> int;
template<class T> auto foo(T&& x forwarded) -> int
{
  auto&& yx = x;
  bar(yx);   // copied.

  auto&& xx forwarded = x; // or auto&&& xx = x;
  bar(xx);    // yes, it's forwarded
}

Which still doesn't break any code.


On Thu, 7 Jun 2018 at 19:44, <mihailnajdenov@gmail.com> wrote:

> This is continuation of a previous topic
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
>
> Hello, I have written a proposal for merging `forward` and `move` behind a
> new postscript operator &&>
>
> This is the initial draft. Feedback is welcome.
>
> Thank You
> MihailNaydenov
>
> --
> 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/eb24413b-3aa0-48e3-ad06-f77e949a498e%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/eb24413b-3aa0-48e3-ad06-f77e949a498e%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALvx3hbbteny_EFMcCcGhD-MS7XsF8N8BT469JaaKh%2BAqK4bFg%40mail.gmail.com.

--000000000000bd273d056e22a15d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><b style=3D"color:rgb(34,34,34);font-family:sans-serif;fon=
t-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-ca=
ps:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px;text-decoration-style:initial=
;text-decoration-color:initial">What&#39;s the motivation?</b><div style=3D=
"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:norma=
l;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;le=
tter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px;text-decoration-style:initial;text-decora=
tion-color:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family=
:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;=
font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:s=
tart;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x;text-decoration-style:initial;text-decoration-color:initial">typing<span>=
=C2=A0</span><font face=3D"monospace, monospace">std::forward&lt;decltype(x=
)&gt;(x)</font><span>=C2=A0</span>is tiresome. The only way to make it pret=
tier, shorter and more expressive is to use a preprocessor macro, than that=
 sucks big time.</div><div style=3D"color:rgb(34,34,34);font-family:sans-se=
rif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-var=
iant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-d=
ecoration-style:initial;text-decoration-color:initial"><br></div><div style=
=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:no=
rmal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400=
;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-dec=
oration-color:initial"><b>Why doesn&#39;t<span>=C2=A0</span><font face=3D"m=
onospace, monospace">std::forward(x)</font><span>=C2=A0</span>work?</b></di=
v><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;f=
ont-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;fon=
t-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tr=
ansform:none;white-space:normal;word-spacing:0px;text-decoration-style:init=
ial;text-decoration-color:initial"><br></div><div style=3D"color:rgb(34,34,=
34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-li=
gatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:norm=
al;text-align:start;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px;text-decoration-style:initial;text-decoration-color:initia=
l">Because when x is an r-value reference,<span>=C2=A0</span><font face=3D"=
monospace, monospace">decltype(x)</font><span>=C2=A0</span>is not the same =
as the type yielded by uttering the name of x.</div><div style=3D"color:rgb=
(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-var=
iant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spaci=
ng:normal;text-align:start;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color=
:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family:sans-seri=
f;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-varia=
nt-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-dec=
oration-style:initial;text-decoration-color:initial"><b>When do we need to =
forward objects?</b></div><div style=3D"color:rgb(34,34,34);font-family:san=
s-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font=
-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start=
;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;te=
xt-decoration-style:initial;text-decoration-color:initial"><br></div><div s=
tyle=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-styl=
e:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight=
:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text=
-decoration-color:initial">When using possibly-rvalue arguments that have b=
een supplied to the current function *and* we wish to use the possible rval=
ue unmolested.</div><div style=3D"color:rgb(34,34,34);font-family:sans-seri=
f;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-varia=
nt-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-dec=
oration-style:initial;text-decoration-color:initial"><br></div><div style=
=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:no=
rmal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400=
;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-dec=
oration-color:initial"><b>Any other times?</b></div><div style=3D"color:rgb=
(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-var=
iant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spaci=
ng:normal;text-align:start;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color=
:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family:sans-seri=
f;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-varia=
nt-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-dec=
oration-style:initial;text-decoration-color:initial">Nope!</div><div style=
=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:no=
rmal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400=
;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-dec=
oration-color:initial"><br></div><div style=3D"color:rgb(34,34,34);font-fam=
ily:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:norm=
al;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-alig=
n:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px;text-decoration-style:initial;text-decoration-color:initial"><b>What i=
f we had a type that allowed x to be the same type as decltype(x) in all ca=
ses?</b></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font=
-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-cap=
s:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoratio=
n-style:initial;text-decoration-color:initial"><br></div><div style=3D"colo=
r:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;fon=
t-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-=
spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-=
color:initial"><b>Would it break any existing code?</b></div><div style=3D"=
color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal=
;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;let=
ter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px;text-decoration-style:initial;text-decorat=
ion-color:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family:=
sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;f=
ont-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:st=
art;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
;text-decoration-style:initial;text-decoration-color:initial">No</div><div =
style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-sty=
le:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weigh=
t:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;tex=
t-decoration-color:initial"><br></div><div style=3D"color:rgb(34,34,34);fon=
t-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures=
:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text=
-align:start;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px;text-decoration-style:initial;text-decoration-color:initial"><b>W=
ould it need a new keyword?</b></div><div style=3D"color:rgb(34,34,34);font=
-family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:=
normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-=
align:start;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px;text-decoration-style:initial;text-decoration-color:initial"><br><=
/div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13p=
x;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;=
font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:i=
nitial;text-decoration-color:initial">No</div><div style=3D"color:rgb(34,34=
,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-l=
igatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:nor=
mal;text-align:start;text-indent:0px;text-transform:none;white-space:normal=
;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initi=
al"><br></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font=
-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-cap=
s:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoratio=
n-style:initial;text-decoration-color:initial"><b>Or a new operator?</b></d=
iv><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;=
font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-t=
ransform:none;white-space:normal;word-spacing:0px;text-decoration-style:ini=
tial;text-decoration-color:initial"><br></div><div style=3D"color:rgb(34,34=
,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-l=
igatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:nor=
mal;text-align:start;text-indent:0px;text-transform:none;white-space:normal=
;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initi=
al">No</div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-s=
ize:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:=
normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-=
style:initial;text-decoration-color:initial"><br></div><div style=3D"color:=
rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-=
variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-sp=
acing:normal;text-align:start;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-co=
lor:initial"><b>Example:</b></div><div style=3D"color:rgb(34,34,34);font-fa=
mily:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:nor=
mal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:start;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px;text-decoration-style:initial;text-decoration-color:initial"><br></di=
v><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;f=
ont-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;fon=
t-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tr=
ansform:none;white-space:normal;word-spacing:0px;text-decoration-style:init=
ial;text-decoration-color:initial"><font face=3D"monospace, monospace">temp=
late&lt;class T&gt; auto foo(T&amp;&amp;&amp; x);</font></div><div style=3D=
"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:norma=
l;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;le=
tter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px;text-decoration-style:initial;text-decora=
tion-color:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family=
:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;=
font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:s=
tart;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x;text-decoration-style:initial;text-decoration-color:initial">x is either =
an l-value reference or an r-value reference. Crucially, using the name `x`=
 will yield the same type.</div><div style=3D"color:rgb(34,34,34);font-fami=
ly:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:norma=
l;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align=
:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px;text-decoration-style:initial;text-decoration-color:initial"><br></div>=
<div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;fon=
t-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-=
weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tran=
sform:none;white-space:normal;word-spacing:0px;text-decoration-style:initia=
l;text-decoration-color:initial"><b>Thus forwarding becomes automatic, triv=
ial and fully specified in its declaration:</b></div><div style=3D"color:rg=
b(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-va=
riant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spac=
ing:normal;text-align:start;text-indent:0px;text-transform:none;white-space=
:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-colo=
r:initial"><br></div><div style=3D"color:rgb(34,34,34);font-family:sans-ser=
if;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-vari=
ant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-de=
coration-style:initial;text-decoration-color:initial"><font face=3D"monospa=
ce, monospace">template&lt;class T&gt; auto foo(T&amp;&amp;&amp; x)</font><=
/div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13p=
x;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;=
font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:i=
nitial;text-decoration-color:initial"><font face=3D"monospace, monospace">{=
</font></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-=
size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps=
:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration=
-style:initial;text-decoration-color:initial"><font face=3D"monospace, mono=
space">=C2=A0 return bar(x);=C2=A0 // x is implicitly forwarded</font></div=
><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;fo=
nt-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font=
-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tra=
nsform:none;white-space:normal;word-spacing:0px;text-decoration-style:initi=
al;text-decoration-color:initial"><font face=3D"monospace, monospace">}</fo=
nt></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size=
:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:nor=
mal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;=
text-transform:none;white-space:normal;word-spacing:0px;text-decoration-sty=
le:initial;text-decoration-color:initial"><br></div><div style=3D"color:rgb=
(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-var=
iant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spaci=
ng:normal;text-align:start;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color=
:initial">This cannot break code because there is no such thing as a refere=
nce to an r-value reference or an rvalue-ref to an lvalue-ref.</div><div st=
yle=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style=
:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:=
400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:n=
one;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-=
decoration-color:initial"><br></div><div style=3D"color:rgb(34,34,34);font-=
family:sans-serif;font-size:13px;font-style:normal;font-variant-ligatures:n=
ormal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-a=
lign:start;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px;text-decoration-style:initial;text-decoration-color:initial"><b>Pos=
sible complaint:</b></div><div style=3D"color:rgb(34,34,34);font-family:san=
s-serif;font-size:13px;font-style:normal;font-variant-ligatures:normal;font=
-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start=
;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;te=
xt-decoration-style:initial;text-decoration-color:initial"><br></div><div s=
tyle=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-styl=
e:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight=
:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text=
-decoration-color:initial"><i>The interface leaks an implementation decisio=
n.</i></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-s=
ize:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:=
normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-=
style:initial;text-decoration-color:initial"><br></div><div style=3D"color:=
rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-=
variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-sp=
acing:normal;text-align:start;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-co=
lor:initial">In which case we could allow the following interface/implement=
ation pair:</div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;f=
ont-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-=
caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decora=
tion-style:initial;text-decoration-color:initial"><br></div><div style=3D"c=
olor:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;=
font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;lett=
er-spacing:normal;text-align:start;text-indent:0px;text-transform:none;whit=
e-space:normal;word-spacing:0px;text-decoration-style:initial;text-decorati=
on-color:initial"><font face=3D"monospace, monospace">template&lt;class T&g=
t; auto foo(T&amp;&amp; x) -&gt; int;</font></div><div style=3D"color:rgb(3=
4,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-varia=
nt-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing=
:normal;text-align:start;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:i=
nitial"><div style=3D"color:rgb(34,34,34);font-size:13px;font-style:normal;=
font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;lett=
er-spacing:normal;text-align:start;text-indent:0px;text-transform:none;whit=
e-space:normal;word-spacing:0px;text-decoration-style:initial;text-decorati=
on-color:initial"><font face=3D"monospace, monospace">template&lt;class T&g=
t; auto foo(T&amp;&amp;&amp; x) -&gt; int</font></div><div style=3D"color:r=
gb(34,34,34);font-size:13px;font-style:normal;font-variant-ligatures:normal=
;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:=
start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px;text-decoration-style:initial;text-decoration-color:initial"><font face=
=3D"monospace, monospace">{</font></div><div style=3D"color:rgb(34,34,34);f=
ont-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-=
caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decora=
tion-style:initial;text-decoration-color:initial"><font face=3D"monospace, =
monospace">=C2=A0 // ...</font></div><div style=3D"color:rgb(34,34,34);font=
-size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-cap=
s:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoratio=
n-style:initial;text-decoration-color:initial"><font face=3D"monospace, mon=
ospace">}</font></div><br class=3D"gmail-Apple-interchange-newline">And if =
we&#39;re going to do that, we could allow another non-keyword annotation a=
l-la override:</div><div style=3D"color:rgb(34,34,34);font-family:sans-seri=
f;font-size:13px;font-style:normal;font-variant-ligatures:normal;font-varia=
nt-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-dec=
oration-style:initial;text-decoration-color:initial"><br></div><div style=
=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:no=
rmal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400=
;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-dec=
oration-color:initial"><div style=3D"color:rgb(34,34,34);font-size:13px;fon=
t-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-=
weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tran=
sform:none;white-space:normal;word-spacing:0px;text-decoration-style:initia=
l;text-decoration-color:initial"><font face=3D"monospace, monospace">templa=
te&lt;class T&gt; auto foo(T&amp;&amp; x) -&gt; int;</font></div><div style=
=3D"color:rgb(34,34,34);font-size:13px;font-style:normal;font-variant-ligat=
ures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;=
text-align:start;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">=
<div style=3D"color:rgb(34,34,34);font-size:13px;font-style:normal;font-var=
iant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spaci=
ng:normal;text-align:start;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color=
:initial"><font face=3D"monospace, monospace">template&lt;class T&gt; auto =
foo(T&amp;&amp; x forwarded) -&gt; int</font></div><div style=3D"color:rgb(=
34,34,34);font-size:13px;font-style:normal;font-variant-ligatures:normal;fo=
nt-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:sta=
rt;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;=
text-decoration-style:initial;text-decoration-color:initial"><font face=3D"=
monospace, monospace">{</font></div><div style=3D"color:rgb(34,34,34);font-=
size:13px;font-style:normal;font-variant-ligatures:normal;font-variant-caps=
:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration=
-style:initial;text-decoration-color:initial"><font face=3D"monospace, mono=
space">=C2=A0 auto&amp;&amp; yx =3D x;</font></div><div style=3D"color:rgb(=
34,34,34);font-size:13px;font-style:normal;font-variant-ligatures:normal;fo=
nt-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:sta=
rt;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;=
text-decoration-style:initial;text-decoration-color:initial"><font face=3D"=
monospace, monospace">=C2=A0 bar(yx);=C2=A0 =C2=A0// copied.</font></div><d=
iv style=3D"color:rgb(34,34,34);font-size:13px;font-style:normal;font-varia=
nt-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing=
:normal;text-align:start;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:i=
nitial"><font face=3D"monospace, monospace"><br></font></div><div style=3D"=
color:rgb(34,34,34);font-size:13px;font-style:normal;font-variant-ligatures=
:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text=
-align:start;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px;text-decoration-style:initial;text-decoration-color:initial"><fon=
t face=3D"monospace, monospace">=C2=A0 auto&amp;&amp; xx forwarded =3D x; /=
/ or auto&amp;&amp;&amp; xx =3D x;</font></div><div style=3D"color:rgb(34,3=
4,34);font-size:13px;font-style:normal;font-variant-ligatures:normal;font-v=
ariant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;t=
ext-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text=
-decoration-style:initial;text-decoration-color:initial"><font face=3D"mono=
space, monospace">=C2=A0 bar(xx);=C2=A0 =C2=A0 // yes, it&#39;s forwarded</=
font></div><div style=3D"color:rgb(34,34,34);font-size:13px;font-style:norm=
al;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;l=
etter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px;text-decoration-style:initial;text-decor=
ation-color:initial"><font face=3D"monospace, monospace">}<br></font></div>=
<br class=3D"gmail-Apple-interchange-newline"></div>Which still doesn&#39;t=
 break any code.</div><br></div><br><div class=3D"gmail_quote"><div dir=3D"=
ltr">On Thu, 7 Jun 2018 at 19:44, &lt;<a href=3D"mailto:mihailnajdenov@gmai=
l.com">mihailnajdenov@gmail.com</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div>This is continuation of a <a href=3D"ht=
tps://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTL=
pbDQAJ" target=3D"_blank">previous topic</a>=C2=A0</div><div><br></div><div=
>Hello, I have written a proposal for merging `forward` and `move` behind a=
 new postscript operator &amp;&amp;&gt;</div><div><br></div><div>This is th=
e initial draft. Feedback is welcome.</div><div><br></div><div>Thank You<br=
></div><div>MihailNaydenov=C2=A0</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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/eb24413b-3aa0-48e3-ad06-f77e949a498e%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/eb24413b-3aa0-=
48e3-ad06-f77e949a498e%40isocpp.org</a>.<br>
</blockquote></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/CALvx3hbbteny_EFMcCcGhD-MS7XsF8N8BT46=
9JaaKh%2BAqK4bFg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbbteny_E=
FMcCcGhD-MS7XsF8N8BT469JaaKh%2BAqK4bFg%40mail.gmail.com</a>.<br />

--000000000000bd273d056e22a15d--

.


Author: florian.csdt@gmail.com
Date: Fri, 8 Jun 2018 08:25:19 -0700 (PDT)
Raw View
------=_Part_30457_1858006135.1528471519743
Content-Type: multipart/alternative;
 boundary="----=_Part_30458_1547733596.1528471519744"

------=_Part_30458_1547733596.1528471519744
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le vendredi 8 juin 2018 16:35:52 UTC+2, mihailn...@gmail.com a =C3=A9crit :
>
>
>
> On Friday, June 8, 2018 at 3:26:03 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le vendredi 8 juin 2018 14:05:11 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>>
>>>
>>>
>>> On Friday, June 8, 2018 at 2:34:31 PM UTC+3, floria...@gmail.com wrote:
>>>>
>>>> Another way to see it is:
>>>>
>>>> Both when you forward and when you move, you promise you will not touc=
h=20
>>>> the object again (except for rebinding it to another value).
>>>>
>>>
>>>
>>> In the case of forwarding reference you can't even rebind or at least=
=20
>>> you should not, much the same way you should not move a frw ref.=20
>>>
>>
>> You cannot rebind a "forwarding" reference only because it might be cons=
t.
>> But if you can ensure somehow it is not const, why couldn't you rebind=
=20
>> it?=20
>>
>
>
> Because it will not "rebind", but override the result of the operation yo=
u forwarded=20
> to.
>
> auto ingr =3D "apple";
> make_cacke(ingr);
> // use what's left from apple... or not
>
> auto make_cacke(auto&& ingr)
> {
>   auto fill =3D make_filling_from_half_apple(ingr&&>);
>
>   ingr =3D "orange";=20
>
>   return make_cake(fill&&>, make_blat(ingr&&>));
> }
>
>
By "rebind", I really mean override.
=20

> =20
>
>>
>>> =20
>>>
>>>> I think that's the key point of this proposal.
>>>>
>>>> I envision the following rules:
>>>> decltype(x) | decltype(x&&>)
>>>> ------------|----------------
>>>> T           | T&&
>>>> T&          | T&
>>>> T&&         | T&&
>>>> const T     | const T&& // implicitely convertible to const T&
>>>> const T&    | const T&
>>>> const T&&   | const T&&
>>>>
>>>> When x is an identifier, it will be equivalent to=20
>>>> std::forward<decltype(x)>(x), and also std::move(x) if in addition x=
=20
>>>> is not a ref.
>>>> Those are the most common cases.
>>>>
>>>> However, this new operator cannot move a ref like std::move does.
>>>>
>>>
>>>
>>>
>>> Currently the proposal moves in all cases *except* if the identifier is=
=20
>>> "forwarding reference". This is - forward *iff*  decltype(x) =3D=3D=20
>>> substitutedType&&
>>>
>>
>> Forwarding references do not exist... Believing they do will bring=20
>> troubles.
>>
>
>
> I think it is better for the C++ language to believe and advertise Forwar=
ding=20
> references.
>
> The deduction rules should be implementation detail.
>
> This makes the language easier to both teach and use
>
>
I would agree with you that it would be nice to have proper forwarding=20
(with or without a special kind of references).
But it would be really difficult to modify the language to have this. And=
=20
I'm not sure it would be worth the effort.

You can teach "forwarding" references right now, but you also need to teach=
=20
the caveats of those (like they do not really exist).
=20

>
> =20
>
>> The only thing that exist is a (not so) special deduction rule.
>> But forwarding is still useful.
>>
>> Here is a code example that works with forward, but will not work with=
=20
>> your operator as you define it because of thinking forwarding references=
=20
>> exist:
>> template <class T>
>> struct Call {
>>   void operator(T&& val) const {
>>     // T is not a "forwarding reference"
>>     bar(std::forward<T>(val)); // this forward will be wrong with your=
=20
>> operator as you specified it
>>   }
>> };
>>
>> template <class T>
>> void foo(T&& val) {
>>   // T here is a "forwarding reference", so no problem here
>>   Call<T>{}(std::forward<T>(val)); // this forward is fine
>> }
>>
>> And yes, that kind of code is actually useful and used, to partially=20
>> specialize a function for instance.
>>
>
>
> Great, great example.=20
>
> On one hand this case I believe *could* be handled as well  - after all=
=20
> you are *still* initializing operator()(T&&) with an "odd" type like oper=
ator()(const=20
> somthing& && )
>

In that example, yes. But I also could use metaprogramming to not write T&&=
=20
but have something that might be equivalent in the end.
You really shouldn't rely on how it is defined. Real world code can be very=
=20
complex.
=20

>
> On the other, *should* it be handled?
> It is easier to reason about the code so that operator(T&&) is accepting=
=20
> an rvalue, and then NOT use &&> so that the code stands out when=20
> forward<T> is used.=20
>

Yes, it should be handled. Wrapping functions should not get more difficult=
=20
with your proposal whose goal is to simplify such wrapping.
=20

>
> Or it might be "nice" to handle this as well?=20
>
> Definitely an open question. Opinions (and expertise) are welcome.
>
> Great example anyway. I will dedicate it a chapter in the next draft.
>
> =20
>
>>
>> =20
>>
>>>
>>> This will make it behave the same way move and forward are used today.
>>>
>>> Yes there are cases of moving a mutating ref. Not just in swap
>>>
>>> void merge(forward_list&& __list)
>>> { merge(std::move(__list), std::less<_Tp>()); }
>>> void
>>> merge(forward_list& __list)
>>> { merge(std::move(__list)); }
>>>
>>
>> This use case is flawed. As you said, the interface is lying. So I don't=
=20
>> expect your operator to move in the second case.
>>
>
>
> Not that much flowed - its a copy and paste from GCC impl of forward_list=
..h=20
> :)
>
> In any case, here it is fine because the function is called "merge" - it=
=20
> implies the argument is "merged into" the destination and no longer exist=
s
>

I agree it's fine because of the name of the function. But one of your=20
selling point is safer moves.
Here it is not safe.
=20

>
> =20
>
>> =20
>>
>>>
>>>
>>> This should work as well under the unified syntax. It will move in=20
>>> *both* cases as __list is *not* substitutedType&&
>>>
>>>
>> The problem with moving lvalue references is that you do not own that=20
>> reference so you cannot/shouldn't give it away.
>> So unless you rebind it to something else afterwards, you shouldn't be=
=20
>> able to move it.
>>
>> So I really would expect giving away an lvalue reference is still an=20
>> lvalue reference.
>>
>
>
> I see, well its a different approach, as said I wish this operator to be=
=20
> direct, drop-in replacement for move and forward so it should behave like=
=20
> them as much as possible.
> I don't want to change the rules, just to have right-by-default language=
=20
> construct.=20
>
>
In my view, it is a drop-in replacement for all forwarding cases, and for=
=20
moves only if you move either a non-reference object (by its identifier) or=
=20
a rvalue reference.
The tricky cases like moving from a lvalue reference still need some=20
thoughts and that's good, because those cases are more error prone.
Make easy tasks easy.



As a final note, I want to highlight something:
void foo(int i, int& j, int&& k) {
  decltype(i); // -> int
  decltype(j); // -> int&
  decltype(k); // -> int&&

  decltype((i)); // -> int&
  decltype((j)); // -> int&
  decltype((k)); // -> int&
}

Problems come from this.
Here you owns i (because it is a local variable): terse move is allowed
k was delegated to you (because rvalue reference): terse move is also=20
allowed
you don't own j, but you can modify it: terse move is not allowed (keep it=
=20
as lvalue reference), but regular move is allowed.

Now, if you think about it, you can write exactly the same with template=20
arguments, and it should give the exact same result.

--=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/5bb9efa4-1f1c-435c-979b-3ed85444e75b%40isocpp.or=
g.

------=_Part_30458_1547733596.1528471519744
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le vendredi 8 juin 2018 16:35:52 UTC+2, mihailn...=
@gmail.com a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 3:26:03 PM UTC+3, <a>fl=
oria...@gmail.com</a> wrote:<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"><br><br>Le vendredi 8 juin 2018 14:05:11 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 2:34:31 PM UTC+3, <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">Another way to see it is:<br><br>Both when you forward and when you mo=
ve, you promise you will not touch the object again (except for rebinding i=
t to another value).<br></div></blockquote><div><br></div><div><br></div><d=
iv>In the case of forwarding reference you can&#39;t even rebind or at leas=
t you should not, much the same way you should not move a frw ref.=C2=A0</d=
iv></div></blockquote><div><br></div><div>You cannot rebind a &quot;forward=
ing&quot; reference only because it might be const.</div><div>But if you ca=
n ensure somehow it is not const, why couldn&#39;t you rebind it?=C2=A0</di=
v></div></blockquote><div><br></div><div><br></div><div>Because it will not=
 &quot;rebind&quot;, but override the result of the operation you <span sty=
le=3D"display:inline!important;float:none;background-color:transparent;colo=
r:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-se=
rif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;le=
tter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;te=
xt-transform:none;white-space:normal;word-spacing:0px">forwarded to</span>.=
</div><div><font face=3D"courier new,monospace"></font><br></div><div><div>=
<font style=3D"border-bottom-color:rgb(34,34,34);border-bottom-style:none;b=
order-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-style:no=
ne;border-left-width:0px;border-right-color:rgb(34,34,34);border-right-styl=
e:none;border-right-width:0px;border-top-color:rgb(34,34,34);border-top-sty=
le:none;border-top-width:0px;margin-bottom:0px;margin-left:0px;margin-right=
:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;p=
adding-top:0px" face=3D"courier new,monospace">auto ingr =3D &quot;apple&qu=
ot;;</font></div><div><span style=3D"background-color:transparent;border-bo=
ttom-color:rgb(34,34,34);border-bottom-style:none;border-bottom-width:0px;b=
order-left-color:rgb(34,34,34);border-left-style:none;border-left-width:0px=
;border-right-color:rgb(34,34,34);border-right-style:none;border-right-widt=
h:0px;border-top-color:rgb(34,34,34);border-top-style:none;border-top-width=
:0px;color:rgb(34,34,34);display:inline;float:none;font-family:courier new,=
monospace;font-size:13px;font-style:normal;font-variant:normal;font-weight:=
400;letter-spacing:normal;margin-bottom:0px;margin-left:0px;margin-right:0p=
x;margin-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;padd=
ing-top:0px;text-align:left;text-decoration:none;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px">make_cacke</span><font style=
=3D"border-bottom-color:rgb(34,34,34);border-bottom-style:none;border-botto=
m-width:0px;border-left-color:rgb(34,34,34);border-left-style:none;border-l=
eft-width:0px;border-right-color:rgb(34,34,34);border-right-style:none;bord=
er-right-width:0px;border-top-color:rgb(34,34,34);border-top-style:none;bor=
der-top-width:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;margin=
-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:=
0px" face=3D"courier new,monospace">(<span style=3D"display:inline!importan=
t;float:none;background-color:transparent;color:rgb(34,34,34);font-family:c=
ourier new,monospace;font-size:13px;font-style:normal;font-variant:normal;f=
ont-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;t=
ext-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">ing=
r</span>);</font></div><div><font style=3D"border-bottom-color:rgb(34,34,34=
);border-bottom-style:none;border-bottom-width:0px;border-left-color:rgb(34=
,34,34);border-left-style:none;border-left-width:0px;border-right-color:rgb=
(34,34,34);border-right-style:none;border-right-width:0px;border-top-color:=
rgb(34,34,34);border-top-style:none;border-top-width:0px;margin-bottom:0px;=
margin-left:0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-=
left:0px;padding-right:0px;padding-top:0px" face=3D"courier new,monospace">=
// use what&#39;s left from apple... or not</font></div><b></b><i></i><u></=
u><sub></sub><sup></sup><strike></strike><br></div><div><font face=3D"couri=
er new,monospace">auto <span style=3D"display:inline!important;float:none;b=
ackground-color:transparent;color:rgb(34,34,34);font-family:courier new,mon=
ospace;font-size:13px;font-style:normal;font-variant:normal;font-weight:400=
;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px=
;text-transform:none;white-space:normal;word-spacing:0px">make_cacke</span>=
(auto&amp;&amp; <span style=3D"display:inline!important;float:none;backgrou=
nd-color:transparent;color:rgb(34,34,34);font-family:courier new,monospace;=
font-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter=
-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text-t=
ransform:none;white-space:normal;word-spacing:0px">ingr</span>)</font></div=
><div><font face=3D"courier new,monospace">{</font></div><div><font face=3D=
"courier new,monospace">=C2=A0 auto fill =3D make_filling_from_half_apple(<=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:courier new,monospace;font-size:13px;fo=
nt-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;t=
ext-align:left;text-decoration:none;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px">i<wbr>ngr</span>&amp;&amp;&gt;);</font><b=
r></div><div><font face=3D"courier new,monospace"></font><br></div><div><fo=
nt face=3D"courier new,monospace">=C2=A0 <span style=3D"background-color:tr=
ansparent;border-bottom-color:rgb(34,34,34);border-bottom-style:none;border=
-bottom-width:0px;border-left-color:rgb(34,34,34);border-left-style:none;bo=
rder-left-width:0px;border-right-color:rgb(34,34,34);border-right-style:non=
e;border-right-width:0px;border-top-color:rgb(34,34,34);border-top-style:no=
ne;border-top-width:0px;color:rgb(34,34,34);display:inline;float:none;font-=
family:courier new,monospace;font-size:13px;font-style:normal;font-variant:=
normal;font-weight:400;letter-spacing:normal;margin-bottom:0px;margin-left:=
0px;margin-right:0px;margin-top:0px;padding-bottom:0px;padding-left:0px;pad=
ding-right:0px;padding-top:0px;text-align:left;text-decoration:none;text-in=
dent:0px;text-transform:none;white-space:normal;word-spacing:0px">ingr </sp=
an>=3D &quot;orange&quot;;=C2=A0</font></div><div><font face=3D"courier new=
,monospace"><br></font></div><div><font face=3D"courier new,monospace">=C2=
=A0 return make_cake(fill&amp;&amp;&gt;, make_blat(ingr&amp;&amp;&gt;));</f=
ont></div><div><font face=3D"courier new,monospace">}</font></div><div><br>=
</div></div></blockquote><div><br></div><div>By &quot;rebind&quot;, I reall=
y mean override.<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></div><div>=C2=A0</div><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"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div><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">I think that&#39;s the key point of thi=
s proposal.<br><br>I envision the following rules:<br><span style=3D"font-f=
amily:courier new,monospace">decltype(x) | decltype(x&amp;&amp;&gt;)<br>---=
---------|----------------<br>T=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>T&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 | T&amp;<br>T&amp;&amp;=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 | T&amp;&amp;<br>const T=C2=A0=C2=A0=C2=A0=C2=A0 | const=
 T&amp;&amp; // implicitely convertible to const T&amp;<br>const T&amp;=C2=
=A0=C2=A0=C2=A0 | const T&amp;<br>const T&amp;&amp;=C2=A0=C2=A0 | const T&a=
mp;&amp;<br></span><br>When <span style=3D"font-family:courier new,monospac=
e">x</span> is an identifier, it will be equivalent to <span style=3D"font-=
family:courier new,monospace">std::forward&lt;decltype(x)&gt;(x)</span>, an=
d also <span style=3D"font-family:courier new,monospace">std::move(x)</span=
> if in addition <span style=3D"font-family:courier new,monospace">x</span>=
 is not a ref.<br>Those are the most common cases.<br><br>However, this new=
 operator cannot move a ref like <span style=3D"font-family:courier new,mon=
ospace">std::move</span> does.<br></div></blockquote><div><br></div><div><b=
r></div><div><br></div><div>Currently the proposal moves in all cases <i>ex=
cept</i> if the identifier is &quot;forwarding reference&quot;. This is - f=
orward <b>iff</b>=C2=A0 <font face=3D"courier new,monospace"><span style=3D=
"text-align:left;color:rgb(34,34,34);text-transform:none;text-indent:0px;le=
tter-spacing:normal;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;text-decoration:none;word-spacing:0px;display:inline!importan=
t;white-space:normal;float:none;background-color:transparent">decltype(x) =
=3D=3D </span>substitutedType&amp;&amp;</font></div></div></blockquote><div=
><br></div><div>Forwarding references do not exist... Believing they do wil=
l bring troubles.</div></div></blockquote><div><br></div><div><br></div><di=
v>I think it is better for the C++ language to believe and advertise=C2=A0<=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px">Forwarding r=
eferences.</span></div><div><span style=3D"display:inline!important;float:n=
one;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Aria=
l&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;f=
ont-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;te=
xt-decoration:none;text-indent:0px;text-transform:none;white-space:normal;w=
ord-spacing:0px"><br></span></div><div><span style=3D"display:inline!import=
ant;float:none;background-color:transparent;color:rgb(34,34,34);font-family=
:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-sty=
le:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-al=
ign:left;text-decoration:none;text-indent:0px;text-transform:none;white-spa=
ce:normal;word-spacing:0px">The deduction rules should be implementation de=
tail.</span></div><div><span style=3D"display:inline!important;float:none;b=
ackground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quo=
t;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-v=
ariant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-de=
coration:none;text-indent:0px;text-transform:none;white-space:normal;word-s=
pacing:0px"><br></span></div><div><span style=3D"display:inline!important;f=
loat:none;background-color:transparent;color:rgb(34,34,34);font-family:&quo=
t;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:no=
rmal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:l=
eft;text-decoration:none;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px">This makes the language easier to both teach and use=
</span></div><div><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><br></span></div></div></blockquote><div><br></div><div>I would agre=
e with you that it would be nice to have proper forwarding (with or without=
 a special kind of references).</div><div>But it would be really difficult =
to modify the language to have this. And I&#39;m not sure it would be worth=
 the effort.</div><div><br></div><div>You can teach &quot;forwarding&quot; =
references right now, but you also need to teach the caveats of those (like=
 they do not really exist).<br></div><div>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px"></span></div><div><b></b><i></i><u></u><=
sub></sub><sup></sup><strike></strike><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>The only thing that exi=
st is a (not so) special deduction rule.</div><div>But forwarding is still =
useful.</div><div><br></div><div>Here is a code example that works with for=
ward, but will not work with your operator as you define it because of thin=
king forwarding references exist:</div><div><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">template</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">struct</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#606">Call</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><span =
style=3D"color:#008">void</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">operator</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&amp;</span><s=
pan style=3D"color:#000"> val</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">const</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">// T i=
s not a &quot;forwarding reference&quot;</span><span style=3D"color:#000"><=
br>=C2=A0 =C2=A0 bar</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">forward</span><span style=3D"color:#660">&lt;</span><span s=
tyle=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</span><span st=
yle=3D"color:#000">val</span><span style=3D"color:#660">));</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#800">// this forward will b=
e wrong with your operator as you specified it</span><span style=3D"color:#=
000"><br>=C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#660">};</span><span style=3D"col=
or:#000"><br><br></span><span style=3D"color:#008">template</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">T</span><span style=3D=
"color:#660">&amp;&amp;</span><span style=3D"color:#000"> val</span><span s=
tyle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><span =
style=3D"color:#800">// T here is a &quot;forwarding reference&quot;, so no=
 problem here</span><span style=3D"color:#000"><br>=C2=A0 </span><span styl=
e=3D"color:#606">Call</span><span style=3D"color:#660">&lt;</span><span sty=
le=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</span><span st=
yle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</span><span s=
tyle=3D"color:#000">val</span><span style=3D"color:#660">)<wbr>);</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#800">// this forward =
is fine</span><span style=3D"color:#000"><br></span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"><br></span></div></code></div></div>=
<div><br></div><div>And yes, that kind of code is actually useful and used,=
 to partially specialize a function for instance.<br></div></div></blockquo=
te><div><br></div><div><br></div><div>Great, great example.=C2=A0</div><div=
><br></div><div>On one hand this case I believe <i>could</i> be handled as =
well=C2=A0 - after all you are <i>still</i> initializing <font face=3D"cour=
ier new,monospace">operator()(T&amp;&amp;)</font> with an &quot;odd&quot; t=
ype like <font face=3D"courier new,monospace">operator()(const somthing&amp=
; &amp;&amp; )</font></div></div></blockquote><div><br></div><div>In that e=
xample, yes. But I also could use metaprogramming to not write T&amp;&amp; =
but have something that might be equivalent in the end.</div><div>You reall=
y shouldn&#39;t rely on how it is defined. Real world code can be very comp=
lex.</div><div>=C2=A0</div><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"><div><font face=3D"courier new,monospace"></font><br></div><d=
iv>On the other, <i>should</i> it be handled?<br></div><div>It is easier to=
 reason about the code so that <font face=3D"courier new,monospace">operato=
r(T&amp;&amp;</font>) is accepting an rvalue, and then NOT use &amp;&amp;&g=
t; so that the code stands out when <font face=3D"courier new,monospace">fo=
rward&lt;T&gt;</font> is used.=C2=A0</div></div></blockquote><div><br></div=
><div>Yes, it should be handled. Wrapping functions should not get more dif=
ficult with your proposal whose goal is to simplify such wrapping.<br></div=
><div>=C2=A0</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><br></div><div>Or it might be &quot;nice&quot; to handle this as =
well?=C2=A0<br></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strik=
e></strike><br></div><div>Definitely an open question. Opinions (and expert=
ise) are welcome.</div><div><br></div><div>Great example anyway. I will ded=
icate it a chapter in the next draft.</div><div><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></div><di=
v>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
><font face=3D"courier new,monospace"></font><br></div><div>This will make =
it behave the same way move and forward are used today.</div><div><br></div=
><div>Yes there are cases of moving a mutating ref. Not just in swap</div><=
font face=3D"courier new,monospace"><br> void merge(forward_list&amp;&amp; =
__list)<br> { merge(std::move(__list), std::less&lt;_Tp&gt;()); }<br> void<=
br> merge(forward_list&amp; __list)<br></font><div><font face=3D"courier ne=
w,monospace"> { merge(std::move(__list)); }</font></div></div></blockquote>=
<div><br></div><div>This use case is flawed. As you said, the interface is =
lying. So I don&#39;t expect your operator to move in the second case.<br><=
/div></div></blockquote><div><br></div><div><br></div><div>Not that much fl=
owed - its a copy and paste from GCC impl of <font face=3D"courier new,mono=
space">forward_list.h </font><font face=3D"arial,sans-serif">:)</font></div=
><div><font face=3D"courier new,monospace"></font><font face=3D"arial,sans-=
serif"></font><br></div><div>In any case, here it is fine because the funct=
ion is called &quot;merge&quot; - it implies the argument is &quot;merged i=
nto&quot; the destination and no longer exists</div></div></blockquote><div=
><br></div><div>I agree it&#39;s fine because of the name of the function. =
But one of your selling point is safer moves.</div><div>Here it is not safe=
..<br></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;"><d=
iv dir=3D"ltr"><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><div>=C2=A0</div><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><br></div><div><br></div><div>=
This should work as well under the unified syntax. It will move in <i>both<=
/i> cases as<font face=3D"courier new,monospace"> __list</font> is <b>not</=
b>=C2=A0<span style=3D"background-color:transparent;border-bottom-color:rgb=
(34,34,34);border-bottom-style:none;border-bottom-width:0px;border-left-col=
or:rgb(34,34,34);border-left-style:none;border-left-width:0px;border-right-=
color:rgb(34,34,34);border-right-style:none;border-right-width:0px;border-t=
op-color:rgb(34,34,34);border-top-style:none;border-top-width:0px;color:rgb=
(34,34,34);display:inline;float:none;font-family:courier new,monospace;font=
-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spa=
cing:normal;margin-bottom:0px;margin-left:0px;margin-right:0px;margin-top:0=
px;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px;te=
xt-align:left;text-decoration:none;text-indent:0px;text-transform:none;whit=
e-space:normal;word-spacing:0px"></span><span style=3D"display:inline!impor=
tant;float:none;background-color:transparent;color:rgb(34,34,34);font-famil=
y:courier new,monospace;font-size:13px;font-style:normal;font-variant:norma=
l;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:non=
e;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">=
substitutedType&amp;&amp;</span></div><div><b></b><i></i><u></u><sub></sub>=
<sup></sup><strike></strike><br></div></div></blockquote><div><br></div><di=
v>The problem with moving lvalue references is that you do not own that ref=
erence so you cannot/shouldn&#39;t give it away.</div><div>So unless you re=
bind it to something else afterwards, you shouldn&#39;t be able to move it.=
</div><div><br></div><div>So I really would expect giving away an lvalue re=
ference is still an lvalue reference.<br></div></div></blockquote><div><br>=
</div><div><br></div><div>I see, well its a different approach, as said I w=
ish this operator to be direct, drop-in replacement for move and forward so=
 it should behave like them as much as possible.</div><div>I don&#39;t want=
 to change the rules, just to have right-by-default language construct.=C2=
=A0</div><div><br></div></div></blockquote><div><br></div><div>In my view, =
it is a drop-in replacement for all forwarding cases, and for moves only if=
 you move either a non-reference object (by its identifier) or a rvalue ref=
erence.</div><div>The tricky cases like moving from a lvalue reference stil=
l need some thoughts and that&#39;s good, because those cases are more erro=
r prone.</div><div>Make easy tasks easy.<br></div><br><br><br>As a final no=
te, I want to highlight something:<br><div style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-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-prettify">void</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> j</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: #008;" class=3D"style=
d-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> k</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: #660;" class=3D"styled-by-prettify">{</span><code clas=
s=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">decltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">i</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// -&gt; int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"></span></code><code class=3D"pret=
typrint"><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">declty=
pe</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">j</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// -&gt; int&amp;</span></code><code class=
=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>decltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">k</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: #800;" class=3D"styled-by-prettify">// -&gt; int&amp;&amp;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></code><br><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"pret=
typrint"><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"=
styled-by-prettify">=C2=A0 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">(i)</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: #800;" class=3D"styled-by-prettify">// -&gt; int&amp;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"></span></co=
de><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">decltype</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">(j)</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// -&gt; int&amp;</s=
pan></code><code class=3D"prettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">(k)</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// -&gt; =
int&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span></code></code></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span></div></code></div><br>Problems come from this.<br>Here you =
owns i (because it is a local variable): terse move is allowed<br>k was del=
egated to you (because rvalue reference): terse move is also allowed<br>you=
 don&#39;t own j, but you can modify it: terse move is not allowed (keep it=
 as lvalue reference), but regular move is allowed.<br><br>Now, if you thin=
k about it, you can write exactly the same with template arguments, and it =
should give the exact same result.<br><br></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/5bb9efa4-1f1c-435c-979b-3ed85444e75b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5bb9efa4-1f1c-435c-979b-3ed85444e75b=
%40isocpp.org</a>.<br />

------=_Part_30458_1547733596.1528471519744--

------=_Part_30457_1858006135.1528471519743--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 8 Jun 2018 08:46:59 -0700 (PDT)
Raw View
------=_Part_62320_845121952.1528472820051
Content-Type: multipart/alternative;
 boundary="----=_Part_62321_355608256.1528472820052"

------=_Part_62321_355608256.1528472820052
Content-Type: text/plain; charset="UTF-8"

On Friday, June 8, 2018 at 10:58:27 AM UTC-4, Richard Hodges wrote:
>
> *What if we had a type that allowed x to be the same type as decltype(x)
> in all cases?*
>

.... what does that even mean, "to be the same type"?

If I have `vector<int> &&& x = ...;`, what is `x`?

You seem to be asking for forwarding references to become a first-class
language feature, rather than an outgrowth of byzantine template reference
deduction mechanics. If that's the case, then you need to specify how they
work *outside* of template deduction.

You seem to be saying that the expression `x` takes on the value category
of the expression used to initialize it. But that's not something you can
do in a function parameter *outside* of the template case, since the
function cannot know how it was initialized. Also, it's not clear what `x`
would mean before its initialization is complete (and yes, you can use
variables before their initialization is complete).

Adding a third kind of reference to the language is not a pleasant thought.

--
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/a5d9499b-5086-4a43-8c2f-4addca7d15ae%40isocpp.org.

------=_Part_62321_355608256.1528472820052
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, June 8, 2018 at 10:58:27 AM UTC-4, Richard Hodg=
es 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"><div=
 style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-st=
yle:normal;font-weight:400;letter-spacing:normal;text-align:start;text-inde=
nt:0px;text-transform:none;white-space:normal;word-spacing:0px"></div><div =
style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-sty=
le:normal;font-weight:400;letter-spacing:normal;text-align:start;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px"><b>What if w=
e had a type that allowed x to be the same type as decltype(x) in all cases=
?</b></div></div></blockquote><div><br></div><div>... what does that even m=
ean, &quot;to be the same type&quot;?</div><div><br></div><div>If I have `v=
ector&lt;int&gt; &amp;&amp;&amp; x =3D ...;`, what is `x`?</div><div><br></=
div><div>You seem to be asking for forwarding references to become a first-=
class language feature, rather than an outgrowth of byzantine template refe=
rence deduction mechanics. If that&#39;s the case, then you need to specify=
 how they work <i>outside</i> of template deduction.</div><div><br></div><d=
iv>You seem to be saying that the expression `x` takes on the value categor=
y of the expression used to initialize it. But that&#39;s not something you=
 can do in a function parameter <i>outside</i> of the template case, since =
the function cannot know how it was initialized. Also, it&#39;s not clear w=
hat `x` would mean before its initialization is complete (and yes, you can =
use variables before their initialization is complete).</div><div><br></div=
><div>Adding a third kind of reference to the language is not a pleasant th=
ought.</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/a5d9499b-5086-4a43-8c2f-4addca7d15ae%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a5d9499b-5086-4a43-8c2f-4addca7d15ae=
%40isocpp.org</a>.<br />

------=_Part_62321_355608256.1528472820052--

------=_Part_62320_845121952.1528472820051--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 8 Jun 2018 18:13:40 +0200
Raw View
--0000000000009ba1d7056e23af06
Content-Type: text/plain; charset="UTF-8"

On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey.semashev@gmail.com>
wrote:

> On 06/08/18 09:32, mihailnajdenov@gmail.com wrote:
> >
> > If one writes a function where he moves instead of forwarding
> >
> >
> >     template< typename T >
> >     void foo(T&& value)
> >     {
> >       vec.push_back(std::move(value));
> >     }
> > **//___^
> > That will be *The Wrong Thing* to do.
>
> There's nothing wrong with it, as long as you actually want to move.
>
> > This is because one /lies against the interface /- T&& is a forwarding
> > reference,/by definition/.
> >
> > Using "object passing", /prevents/ you to lie!
>
> There's no such thing as a forwarding reference in the language.


http://eel.is/c++draft/temp#deduct.call-3.sentence-3

 Using
> T&&, where T is a template argument, for forwarding is just one use
> case, but there are also other. For example, this syntax can be used for
> generalization so that you don't have to write multiple overloads for
> different argument types.
>
> > See a similar post from the original discussion for detailed explanation
> >
> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>
> Using SFINAE to force users to explicitly move is a good approach, but I
> don't think it is always necessary. If my foo function is called, say,
> foo_move and is properly documented, there's no reason to force users to
> explicitly call std::move on their end. Especially, if the user is me,
> the implementer of foo_move.
>
> >     Forwarding and moving a value have a fundamental difference in
> >     strength.
> >     Forwarding does not move the value unless permitted by the program
> >     (i.e.
> >     the value is assumed to be unused afterwards) while std::move is
> >     stronger and will move even lvalue. The fact that both may end up
> >     moving
> >     the value does not mean they are the same and should be expressed the
> >     same way. Being more explicit about the intent is beneficial to the
> >     developer, experienced or junior.
> >
> > Question is what is the original intend? And actually the intend in both
> > cases is to give the object away.
>
> That's from the function caller's perspective. And as far as the caller
> is concerned, if you want to move, you use std::move. You never use
> std::forward to move a value.
>
> As a function implementer (or, more accurately, receiver of the function
> arguments), you can have different intentions wrt. the arguments. Some
> of the arguments you may move, others forward, thirds modify or copy. My
> point is that the compiler is not able and should not be given liberty
> to decide which behavior to apply in each case. And the end code will
> have better quality if this intent is apparent.
>
> > About the "ugliness".
> >
> > Well, I really hoped a simple && would do the trick, but it does clash
> > with the binary operator && and I see no way around that.
> >
> > An alternative might be val~~ or val~&& or just val~ or a keyword val
> > passin.
>
> These don't look any better to me, sorry. Ignoring for a moment that I
> don't like the idea to begin with, I would prefer a function-style
> keyword instead of new obscure operators, especially 3 or more
> characters long.
>
> --
> 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/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
> .
>

--
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/CAOfiQq%3D8io5-gDgxOsueJD8WFa2-zdesnu35FAbSAQu9DPSatg%40mail.gmail.com.

--0000000000009ba1d7056e23af06
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, =
8 Jun 2018, 10:33 Andrey Semashev, &lt;<a href=3D"mailto:andrey.semashev@gm=
ail.com">andrey.semashev@gmail.com</a>&gt; wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">On 06/08/18 09:32, <a href=3D"mailto:mihailnajdenov@gmail.co=
m" target=3D"_blank" rel=3D"noreferrer">mihailnajdenov@gmail.com</a> wrote:=
<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a href=3D"=
http://eel.is/c++draft/temp#deduct.call-3.sentence-3">http://eel.is/c++draf=
t/temp#deduct.call-3.sentence-3</a><br></div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/=
Kdt1dVwL7bo/Gld277dtDQAJ" rel=3D"noreferrer noreferrer" target=3D"_blank">h=
ttps://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld27=
7dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/095ad277-7800-53e2-35cc-16d11e1c65d9%=
40gmail.com" rel=3D"noreferrer noreferrer" target=3D"_blank">https://groups=
..google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d1=
1e1c65d9%40gmail.com</a>.<br>
</blockquote></div></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/CAOfiQq%3D8io5-gDgxOsueJD8WFa2-zdesnu=
35FAbSAQu9DPSatg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3D8io5-=
gDgxOsueJD8WFa2-zdesnu35FAbSAQu9DPSatg%40mail.gmail.com</a>.<br />

--0000000000009ba1d7056e23af06--

.


Author: florian.csdt@gmail.com
Date: Fri, 8 Jun 2018 09:19:47 -0700 (PDT)
Raw View
------=_Part_17873_540936740.1528474787349
Content-Type: multipart/alternative;
 boundary="----=_Part_17874_1040496127.1528474787349"

------=_Part_17874_1040496127.1528474787349
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le vendredi 8 juin 2018 18:13:59 UTC+2, Richard Smith a =C3=A9crit :
>
> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com=20
> <javascript:>> wrote:
>
>> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
>> >=20
>> > If one writes a function where he moves instead of forwarding
>> >=20
>> >=20
>> >     template< typename T >
>> >     void foo(T&& value)
>> >     {
>> >       vec.push_back(std::move(value));
>> >     }
>> > **//___^
>> > That will be *The Wrong Thing* to do.
>>
>> There's nothing wrong with it, as long as you actually want to move.
>>
>> > This is because one /lies against the interface /- T&& is a forwarding=
=20
>> > reference,/by definition/.
>> >=20
>> > Using "object passing", /prevents/ you to lie!
>>
>> There's no such thing as a forwarding reference in the language.
>
>
> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>
>
This is not part of the type system. It is used only to adapt template=20
argument deduction. The information of such a "forwarding" reference is=20
lost afterwards.

--=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/464067e8-fe57-45a5-bceb-032ee5bb633c%40isocpp.or=
g.

------=_Part_17874_1040496127.1528474787349
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le vendredi 8 juin 2018 18:13:59 UTC+2, Richard Sm=
ith a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2=
018, 10:33 Andrey Semashev, &lt;<a href=3D"javascript:" target=3D"_blank" g=
df-obfuscated-mailto=3D"e9O7oR40BQAJ" rel=3D"nofollow" onmousedown=3D"this.=
href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;java=
script:&#39;;return true;">andrey....@gmail.com</a>&gt; wrote:<br></div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex">On 06/08/18 09:32, <a href=3D"javascript:" rel=
=3D"nofollow" target=3D"_blank" gdf-obfuscated-mailto=3D"e9O7oR40BQAJ" onmo=
usedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.=
href=3D&#39;javascript:&#39;;return true;">mihailn...@gmail.com</a> wrote:<=
br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a href=3D"=
http://eel.is/c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x=
3dhttp%3A%2F%2Feel.is%2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;retur=
n true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A=
%2F%2Feel.is%2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x2=
6sntz\x3d1\x26usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div><br>=
</div></blockquote><div><br></div><div>This is not part of the type system.=
 It is used only to adapt template argument deduction. The information of s=
uch a &quot;forwarding&quot; reference is lost afterwards.</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/464067e8-fe57-45a5-bceb-032ee5bb633c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/464067e8-fe57-45a5-bceb-032ee5bb633c=
%40isocpp.org</a>.<br />

------=_Part_17874_1040496127.1528474787349--

------=_Part_17873_540936740.1528474787349--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 8 Jun 2018 20:03:24 +0200
Raw View
--000000000000835072056e2539f5
Content-Type: text/plain; charset="UTF-8"

On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges <hodges.r@gmail.com> wrote:

> template<class T> auto foo(T&&& x)
>
{
>   return bar(x);  // x is implicitly forwarded
> }
>

What about:

template<class T> auto foo(T&&& x)
{
    checkprecondition(x);  // x is implicitly forwarded
    return bar(x);         // oops, sometimes
}


 --
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--
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/CAGg_6%2BOjCFd0aOZy%3DLYw11hpPnZgWOD%2BnydxEYmW6Od3A_6ebw%40mail.gmail.com.

--000000000000835072056e2539f5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges &lt;<a href=
=3D"mailto:hodges.r@gmail.com">hodges.r@gmail.com</a>&gt; wrote:<br><div cl=
ass=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-colo=
r:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div style=3D"color:r=
gb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-v=
ariant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spa=
cing:normal;text-align:start;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px"><span style=3D"font-family:monospace,monospace">=
template&lt;class T&gt; auto foo(T&amp;&amp;&amp; x)</span><br></div></div>=
</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(2=
04,204,204);padding-left:1ex"><div dir=3D"ltr"><div style=3D"color:rgb(34,3=
4,34);font-family:sans-serif;font-size:13px;font-style:normal;font-variant-=
ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:no=
rmal;text-align:start;text-indent:0px;text-transform:none;white-space:norma=
l;word-spacing:0px"><font face=3D"monospace, monospace">{</font></div><div =
style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-sty=
le:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weigh=
t:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px"><font face=3D"monospace, monospa=
ce">=C2=A0 return bar(x);=C2=A0 // x is implicitly forwarded</font></div><d=
iv style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-=
style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-we=
ight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px"><font face=3D"monospace, mono=
space">}</font></div></div></blockquote><div><br></div><div>What about:</di=
v><div><br></div><div><div><div style=3D"font-variant-ligatures:normal"><sp=
an style=3D"font-family:monospace,monospace">template&lt;class T&gt; auto f=
oo(T&amp;&amp;&amp; x)</span><br></div></div><span style=3D"font-family:mon=
ospace,monospace">{</span><br><div><div style=3D"font-variant-ligatures:nor=
mal"><font face=3D"monospace, monospace">=C2=A0 =C2=A0 checkprecondition(x)=
; =C2=A0</font><span style=3D"font-family:monospace,monospace">// x is impl=
icitly forwarded</span></div></div><span style=3D"font-family:monospace,mon=
ospace">=C2=A0 =C2=A0 return bar(x); =C2=A0 =C2=A0 =C2=A0 =C2=A0 // oops, s=
ometimes</span><br><span style=3D"font-family:monospace,monospace">}</span>=
<br><div><div><font face=3D"monospace, monospace"><br></font></div></div></=
div><div><font face=3D"monospace, monospace"><br></font></div><div>=C2=A0--=
=C2=A0</div></div><div dir=3D"ltr" class=3D"gmail_signature"><div dir=3D"lt=
r"><div><div dir=3D"ltr"><div>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;m=
ailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@evi=
loverlord.com</a>&gt; =C2=A0+1-847-691-1404</div></div></div></div></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/CAGg_6%2BOjCFd0aOZy%3DLYw11hpPnZgWOD%=
2BnydxEYmW6Od3A_6ebw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BOj=
CFd0aOZy%3DLYw11hpPnZgWOD%2BnydxEYmW6Od3A_6ebw%40mail.gmail.com</a>.<br />

--000000000000835072056e2539f5--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 8 Jun 2018 11:30:01 -0700 (PDT)
Raw View
------=_Part_63488_1385923908.1528482601257
Content-Type: multipart/alternative;
 boundary="----=_Part_63489_1537716859.1528482601257"

------=_Part_63489_1537716859.1528482601257
Content-Type: text/plain; charset="UTF-8"

On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin ":-)" Liber wrote:
>
> On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges <hodg...@gmail.com
> <javascript:>> wrote:
>
>> template<class T> auto foo(T&&& x)
>>
> {
>>   return bar(x);  // x is implicitly forwarded
>> }
>>
>
> What about:
>
> template<class T> auto foo(T&&& x)
> {
>     checkprecondition(x);  // x is implicitly forwarded
>     return bar(x);         // oops, sometimes
> }
>
>
That rather depends on `checkprecondition`'s parameters, yes? If it takes
everything as a `const&`, then it should be fine to forward the parameter
to both. And really, a function with that name has no business modifying
its parameters.

--
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/cd4b0d4c-cada-4010-9633-0072d85fb8e9%40isocpp.org.

------=_Part_63489_1537716859.1528482601257
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin &quot;:=
-)&quot; Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges &lt;<a href=3D"javas=
cript:" target=3D"_blank" gdf-obfuscated-mailto=3D"zHGkhiA6BQAJ" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" oncli=
ck=3D"this.href=3D&#39;javascript:&#39;;return true;">hodg...@gmail.com</a>=
&gt; wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:=
solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"=
><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;fo=
nt-style:normal;font-weight:400;letter-spacing:normal;text-align:start;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span =
style=3D"font-family:monospace,monospace">template&lt;class T&gt; auto foo(=
T&amp;&amp;&amp; x)</span><br></div></div></blockquote><blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font=
-size:13px;font-style:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:start;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><font face=3D"monospace, monospace">{</font></div><div style=3D"colo=
r:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style:normal;fon=
t-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-tr=
ansform:none;white-space:normal;word-spacing:0px"><font face=3D"monospace, =
monospace">=C2=A0 return bar(x);=C2=A0 // x is implicitly forwarded</font><=
/div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13p=
x;font-style:normal;font-weight:400;letter-spacing:normal;text-align:start;=
text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><f=
ont face=3D"monospace, monospace">}</font></div></div></blockquote><div><br=
></div><div>What about:</div><div><br></div><div><div><div><span style=3D"f=
ont-family:monospace,monospace">template&lt;class T&gt; auto foo(T&amp;&amp=
;&amp; x)</span><br></div></div><span style=3D"font-family:monospace,monosp=
ace">{</span><br><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 checkprecondition(x); =C2=A0</font><span style=3D"font-family:monospace=
,monospace">// x is implicitly forwarded</span></div></div><span style=3D"f=
ont-family:monospace,monospace">=C2=A0 =C2=A0 return bar(x); =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 // oops, sometimes</span><br><span style=3D"font-family:monos=
pace,monospace">}</span><br><div><div><font face=3D"monospace, monospace"><=
br></font></div></div></div></div></div></blockquote><div><br></div><div>Th=
at rather depends on `checkprecondition`&#39;s parameters, yes? If it takes=
 everything as a `const&amp;`, then it should be fine to forward the parame=
ter to both. And really, a function with that name has no business modifyin=
g its parameters.<br></div><br></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/cd4b0d4c-cada-4010-9633-0072d85fb8e9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/cd4b0d4c-cada-4010-9633-0072d85fb8e9=
%40isocpp.org</a>.<br />

------=_Part_63489_1537716859.1528482601257--

------=_Part_63488_1385923908.1528482601257--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 8 Jun 2018 20:41:41 +0200
Raw View
--0000000000006d6613056e25c2a9
Content-Type: text/plain; charset="UTF-8"

On Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas <jmckesson@gmail.com> wrote:

> On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>
>> On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges <hodg...@gmail.com> wrote:
>>
>>> template<class T> auto foo(T&&& x)
>>>
>> {
>>>   return bar(x);  // x is implicitly forwarded
>>> }
>>>
>>
>> What about:
>>
>> template<class T> auto foo(T&&& x)
>> {
>>     checkprecondition(x);  // x is implicitly forwarded
>>     return bar(x);         // oops, sometimes
>> }
>>
>>
> That rather depends on `checkprecondition`'s parameters, yes? If it takes
> everything as a `const&`, then it should be fine to forward the parameter
> to both. And really, a function with that name has no business modifying
> its parameters.
>

The current rule is (roughly) if it has a name, it is an l-value.  With
this idea, there is nothing visual at any call site indicating how x will
be treated.  Now, one can argue this isn't much worse, because there is
nothing at the call site to indicate call by value or call by (possibly
qualified cv) reference, but you'd have to consider that.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  +1-847-691-1404

--
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/CAGg_6%2BN8-PW_cijwt_DeUfy8Y%3D-gX88LSv7fndyZTy3-CvpO1A%40mail.gmail.com.

--0000000000006d6613056e25c2a9
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas &lt;<a href=3D"=
mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt; w=
rote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr">On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin &quot;:-)&quot;=
 Liber wrote:<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">On Fr=
i, Jun 8, 2018 at 4:58 PM Richard Hodges &lt;<a rel=3D"nofollow">hodg...@gm=
ail.com</a>&gt; wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-family:sans-serif;font-s=
ize:13px;font-style:normal;font-weight:400;letter-spacing:normal;text-align=
:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px"><span style=3D"font-family:monospace,monospace">template&lt;class T&gt=
; auto foo(T&amp;&amp;&amp; x)</span><br></div></div></blockquote><blockquo=
te class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-widt=
h:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-le=
ft:1ex"><div dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-family:sans=
-serif;font-size:13px;font-style:normal;font-weight:400;letter-spacing:norm=
al;text-align:start;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><font face=3D"monospace, monospace">{</font></div><div st=
yle=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-style=
:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:=
0px;text-transform:none;white-space:normal;word-spacing:0px"><font face=3D"=
monospace, monospace">=C2=A0 return bar(x);=C2=A0 // x is implicitly forwar=
ded</font></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;fo=
nt-size:13px;font-style:normal;font-weight:400;letter-spacing:normal;text-a=
lign:start;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px"><font face=3D"monospace, monospace">}</font></div></div></blockquo=
te><div><br></div><div>What about:</div><div><br></div><div><div><div><span=
 style=3D"font-family:monospace,monospace">template&lt;class T&gt; auto foo=
(T&amp;&amp;&amp; x)</span><br></div></div><span style=3D"font-family:monos=
pace,monospace">{</span><br><div><div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 checkprecondition(x); =C2=A0</font><span style=3D"font-family=
:monospace,monospace">// x is implicitly forwarded</span></div></div><span =
style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 return bar(x); =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 // oops, sometimes</span><br><span style=3D"font-f=
amily:monospace,monospace">}</span><br><div><div><font face=3D"monospace, m=
onospace"><br></font></div></div></div></div></div></blockquote><div><br></=
div><div>That rather depends on `checkprecondition`&#39;s parameters, yes? =
If it takes everything as a `const&amp;`, then it should be fine to forward=
 the parameter to both. And really, a function with that name has no busine=
ss modifying its parameters.<br></div></div></blockquote><div><br></div><di=
v>The current rule is (roughly) if it has a name, it is an l-value.=C2=A0 W=
ith this idea, there is nothing visual at any call site indicating how x wi=
ll be treated.=C2=A0 Now, one can argue this isn&#39;t much worse, because =
there is nothing at the call site to indicate call by value or call by (pos=
sibly qualified cv) reference, but you&#39;d have to consider that.</div></=
div>-- <br><div dir=3D"ltr" class=3D"m_-3407680115089685389gmail_signature"=
 data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><div><div dir=3D"ltr">=
<div>=C2=A0Nevin &quot;:-)&quot; Liber=C2=A0 &lt;mailto:<a href=3D"mailto:n=
evin@eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt; =C2=
=A0+1-847-691-1404</div></div></div></div></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/CAGg_6%2BN8-PW_cijwt_DeUfy8Y%3D-gX88L=
Sv7fndyZTy3-CvpO1A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BN8-P=
W_cijwt_DeUfy8Y%3D-gX88LSv7fndyZTy3-CvpO1A%40mail.gmail.com</a>.<br />

--0000000000006d6613056e25c2a9--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 8 Jun 2018 11:57:22 -0700 (PDT)
Raw View
------=_Part_55849_893129700.1528484242321
Content-Type: multipart/alternative;
 boundary="----=_Part_55850_278281429.1528484242321"

------=_Part_55850_278281429.1528484242321
Content-Type: text/plain; charset="UTF-8"

On Friday, June 8, 2018 at 2:42:20 PM UTC-4, Nevin ":-)" Liber wrote:
>
> On Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>>
>>> On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges <hodg...@gmail.com> wrote:
>>>
>>>> template<class T> auto foo(T&&& x)
>>>>
>>> {
>>>>   return bar(x);  // x is implicitly forwarded
>>>> }
>>>>
>>>
>>> What about:
>>>
>>> template<class T> auto foo(T&&& x)
>>> {
>>>     checkprecondition(x);  // x is implicitly forwarded
>>>     return bar(x);         // oops, sometimes
>>> }
>>>
>>>
>> That rather depends on `checkprecondition`'s parameters, yes? If it takes
>> everything as a `const&`, then it should be fine to forward the parameter
>> to both. And really, a function with that name has no business modifying
>> its parameters.
>>
>
> The current rule is (roughly) if it has a name, it is an l-value.  With
> this idea, there is nothing visual at any call site indicating how x will
> be treated.  Now, one can argue this isn't much worse, because there is
> nothing at the call site to indicate call by value or call by (possibly
> qualified cv) reference, but you'd have to consider that.
>

I can agree with that. Indeed, I think annotation at the point of use for
move/forward was one of the best things to come out of C++11.

Really though, I think as a meta-rule of C++ feature design, we should say
that if the best solution to a C++ problem is to introduce a *third* kind
of reference... it either isn't the best solution or it's not a problem
that's *worth solving*.

I'd go with the former here. A simplified annotation at the point of use
(whatever that annotation may be) is far better than a new reference type.

--
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/23af17ac-1c0e-4828-ade7-4b1ab00c601a%40isocpp.org.

------=_Part_55850_278281429.1528484242321
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, June 8, 2018 at 2:42:20 PM UTC-4, Nevin &quot;:=
-)&quot; Liber wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas &lt;<a href=3D"javascri=
pt:" target=3D"_blank" gdf-obfuscated-mailto=3D"3HOJAzc8BQAJ" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=
=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.com</a>&g=
t; wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr">On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin &quot;:-)&q=
uot; Liber 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">O=
n Fri, Jun 8, 2018 at 4:58 PM Richard Hodges &lt;<a rel=3D"nofollow">hodg..=
..@gmail.com</a>&gt; wrote:<br><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-family:sans-serif;f=
ont-size:13px;font-style:normal;font-weight:400;letter-spacing:normal;text-=
align:start;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px"><span style=3D"font-family:monospace,monospace">template&lt;class=
 T&gt; auto foo(T&amp;&amp;&amp; x)</span><br></div></div></blockquote><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);paddi=
ng-left:1ex"><div dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font-family=
:sans-serif;font-size:13px;font-style:normal;font-weight:400;letter-spacing=
:normal;text-align:start;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px"><font face=3D"monospace, monospace">{</font></div><d=
iv style=3D"color:rgb(34,34,34);font-family:sans-serif;font-size:13px;font-=
style:normal;font-weight:400;letter-spacing:normal;text-align:start;text-in=
dent:0px;text-transform:none;white-space:normal;word-spacing:0px"><font fac=
e=3D"monospace, monospace">=C2=A0 return bar(x);=C2=A0 // x is implicitly f=
orwarded</font></div><div style=3D"color:rgb(34,34,34);font-family:sans-ser=
if;font-size:13px;font-style:normal;font-weight:400;letter-spacing:normal;t=
ext-align:start;text-indent:0px;text-transform:none;white-space:normal;word=
-spacing:0px"><font face=3D"monospace, monospace">}</font></div></div></blo=
ckquote><div><br></div><div>What about:</div><div><br></div><div><div><div>=
<span style=3D"font-family:monospace,monospace">template&lt;class T&gt; aut=
o foo(T&amp;&amp;&amp; x)</span><br></div></div><span style=3D"font-family:=
monospace,monospace">{</span><br><div><div><font face=3D"monospace, monospa=
ce">=C2=A0 =C2=A0 checkprecondition(x); =C2=A0</font><span style=3D"font-fa=
mily:monospace,monospace">// x is implicitly forwarded</span></div></div><s=
pan style=3D"font-family:monospace,monospace">=C2=A0 =C2=A0 return bar(x); =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // oops, sometimes</span><br><span style=3D"fon=
t-family:monospace,monospace">}</span><br><div><div><font face=3D"monospace=
, monospace"><br></font></div></div></div></div></div></blockquote><div><br=
></div><div>That rather depends on `checkprecondition`&#39;s parameters, ye=
s? If it takes everything as a `const&amp;`, then it should be fine to forw=
ard the parameter to both. And really, a function with that name has no bus=
iness modifying its parameters.<br></div></div></blockquote><div><br></div>=
<div>The current rule is (roughly) if it has a name, it is an l-value.=C2=
=A0 With this idea, there is nothing visual at any call site indicating how=
 x will be treated.=C2=A0 Now, one can argue this isn&#39;t much worse, bec=
ause there is nothing at the call site to indicate call by value or call by=
 (possibly qualified cv) reference, but you&#39;d have to consider that.</d=
iv></div></div></blockquote><div><br></div><div>I can agree with that. Inde=
ed, I think annotation at the point of use for move/forward was one of the =
best things to come out of C++11.<br></div><div><br></div><div>Really thoug=
h, I think as a meta-rule of C++ feature design, we should say that if the =
best solution to a C++ problem is to introduce a <i>third</i> kind of refer=
ence... it either isn&#39;t the best solution or it&#39;s not a problem tha=
t&#39;s <i>worth solving</i>.</div><div><br></div><div>I&#39;d go with the =
former here. A simplified annotation at the point of use (whatever that ann=
otation may be) is far better than a new reference type.</div><br></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/23af17ac-1c0e-4828-ade7-4b1ab00c601a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/23af17ac-1c0e-4828-ade7-4b1ab00c601a=
%40isocpp.org</a>.<br />

------=_Part_55850_278281429.1528484242321--

------=_Part_55849_893129700.1528484242321--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Sat, 9 Jun 2018 08:54:05 +0200
Raw View
--000000000000373de0056e2ffcab
Content-Type: text/plain; charset="UTF-8"

On Fri, 8 Jun 2018 at 20:57, Nicol Bolas <jmckesson@gmail.com> wrote:

> On Friday, June 8, 2018 at 2:42:20 PM UTC-4, Nevin ":-)" Liber wrote:
>>
>> On Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Friday, June 8, 2018 at 2:04:04 PM UTC-4, Nevin ":-)" Liber wrote:
>>>>
>>>> On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges <hodg...@gmail.com>
>>>> wrote:
>>>>
>>>>> template<class T> auto foo(T&&& x)
>>>>>
>>>> {
>>>>>   return bar(x);  // x is implicitly forwarded
>>>>> }
>>>>>
>>>>
>>>> What about:
>>>>
>>>> template<class T> auto foo(T&&& x)
>>>> {
>>>>     checkprecondition(x);  // x is implicitly forwarded
>>>>     return bar(x);         // oops, sometimes
>>>> }
>>>>
>>>>
>>> That rather depends on `checkprecondition`'s parameters, yes? If it
>>> takes everything as a `const&`, then it should be fine to forward the
>>> parameter to both. And really, a function with that name has no business
>>> modifying its parameters.
>>>
>>
>> The current rule is (roughly) if it has a name, it is an l-value.  With
>> this idea, there is nothing visual at any call site indicating how x will
>> be treated.  Now, one can argue this isn't much worse, because there is
>> nothing at the call site to indicate call by value or call by (possibly
>> qualified cv) reference, but you'd have to consider that.
>>
>
> I can agree with that. Indeed, I think annotation at the point of use for
> move/forward was one of the best things to come out of C++11.
>
> Really though, I think as a meta-rule of C++ feature design, we should say
> that if the best solution to a C++ problem is to introduce a *third* kind
> of reference... it either isn't the best solution or it's not a problem
> that's *worth solving*.
>
> I'd go with the former here. A simplified annotation at the point of use
> (whatever that annotation may be) is far better than a new reference type.
>

On balance I agree with you.

If a new keyword is unacceptable (and truly, I believe there is more
resistance to this idea than there ought to be) then a new postfix
annotation half-keyword at the point of use is fine by me.

template<class T>
auto foo(T&& x)
{
  return bar(x forwarded);  // can't see a problem with this
}

template<class T>
auto foo(T&& x)
{
  return bar(fwd(x));  // but frankly I can't see a problem with this either
}



> --
> 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/23af17ac-1c0e-4828-ade7-4b1ab00c601a%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/23af17ac-1c0e-4828-ade7-4b1ab00c601a%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALvx3hZnpPGJ8gufQb%3Dm%3DnuT1GkkpCQXAuNSJ-wMFGSWrbPMAA%40mail.gmail.com.

--000000000000373de0056e2ffcab
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri=
, 8 Jun 2018 at 20:57, Nicol Bolas &lt;<a href=3D"mailto:jmckesson@gmail.co=
m">jmckesson@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr">On Friday, June 8, 2018 at 2:42:20 PM UTC-4, Nevin &quo=
t;:-)&quot; Liber 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 Fri, Jun 8, 2018 at 8:30 PM Nicol Bolas &lt;<a rel=3D"nofollow">jm=
ck...@gmail.com</a>&gt; wrote:<br><div class=3D"gmail_quote"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr">On Friday, June 8, 2018 at 2:04:04 PM UTC=
-4, Nevin &quot;:-)&quot; Liber wrote:<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">On Fri, Jun 8, 2018 at 4:58 PM Richard Hodges &lt;<a re=
l=3D"nofollow">hodg...@gmail.com</a>&gt; wrote:<br><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><div style=3D"color:rgb(34,34,34);font=
-family:sans-serif;font-size:13px;font-style:normal;font-weight:400;letter-=
spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px"><span style=3D"font-family:monospace,monospac=
e">template&lt;class T&gt; auto foo(T&amp;&amp;&amp; x)</span><br></div></d=
iv></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div style=3D"color:rgb(3=
4,34,34);font-family:sans-serif;font-size:13px;font-style:normal;font-weigh=
t:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px"><font face=3D"monospace, monospa=
ce">{</font></div><div style=3D"color:rgb(34,34,34);font-family:sans-serif;=
font-size:13px;font-style:normal;font-weight:400;letter-spacing:normal;text=
-align:start;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px"><font face=3D"monospace, monospace">=C2=A0 return bar(x);=C2=A0 =
// x is implicitly forwarded</font></div><div style=3D"color:rgb(34,34,34);=
font-family:sans-serif;font-size:13px;font-style:normal;font-weight:400;let=
ter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px"><font face=3D"monospace, monospace">}</fo=
nt></div></div></blockquote><div><br></div><div>What about:</div><div><br><=
/div><div><div><div><span style=3D"font-family:monospace,monospace">templat=
e&lt;class T&gt; auto foo(T&amp;&amp;&amp; x)</span><br></div></div><span s=
tyle=3D"font-family:monospace,monospace">{</span><br><div><div><font face=
=3D"monospace, monospace">=C2=A0 =C2=A0 checkprecondition(x); =C2=A0</font>=
<span style=3D"font-family:monospace,monospace">// x is implicitly forwarde=
d</span></div></div><span style=3D"font-family:monospace,monospace">=C2=A0 =
=C2=A0 return bar(x); =C2=A0 =C2=A0 =C2=A0 =C2=A0 // oops, sometimes</span>=
<br><span style=3D"font-family:monospace,monospace">}</span><br><div><div><=
font face=3D"monospace, monospace"><br></font></div></div></div></div></div=
></blockquote><div><br></div><div>That rather depends on `checkprecondition=
`&#39;s parameters, yes? If it takes everything as a `const&amp;`, then it =
should be fine to forward the parameter to both. And really, a function wit=
h that name has no business modifying its parameters.<br></div></div></bloc=
kquote><div><br></div><div>The current rule is (roughly) if it has a name, =
it is an l-value.=C2=A0 With this idea, there is nothing visual at any call=
 site indicating how x will be treated.=C2=A0 Now, one can argue this isn&#=
39;t much worse, because there is nothing at the call site to indicate call=
 by value or call by (possibly qualified cv) reference, but you&#39;d have =
to consider that.</div></div></div></blockquote><div><br></div><div>I can a=
gree with that. Indeed, I think annotation at the point of use for move/for=
ward was one of the best things to come out of C++11.<br></div><div><br></d=
iv><div>Really though, I think as a meta-rule of C++ feature design, we sho=
uld say that if the best solution to a C++ problem is to introduce a <i>thi=
rd</i> kind of reference... it either isn&#39;t the best solution or it&#39=
;s not a problem that&#39;s <i>worth solving</i>.</div><div><br></div><div>=
I&#39;d go with the former here. A simplified annotation at the point of us=
e (whatever that annotation may be) is far better than a new reference type=
..</div></div></blockquote><div><br></div><div>On balance I agree with you.<=
/div><div><br></div><div>If a new keyword is unacceptable (and truly, I bel=
ieve there is more resistance to this idea than there ought to be) then a n=
ew postfix annotation half-keyword at the point of use is fine by me.</div>=
<div><br></div><div><font face=3D"monospace, monospace">template&lt;class T=
&gt;</font></div><div><font face=3D"monospace, monospace">auto foo(T&amp;&a=
mp; x)</font></div><div><font face=3D"monospace, monospace">{</font></div><=
div><font face=3D"monospace, monospace">=C2=A0 return bar(x forwarded);=C2=
=A0 // can&#39;t see a problem with this</font></div><div><font face=3D"mon=
ospace, monospace">}=C2=A0=C2=A0</font></div><div><font face=3D"monospace, =
monospace"><br></font></div><div><font face=3D"monospace, monospace"><div s=
tyle=3D"font-family:sans-serif;background-color:rgb(255,255,255);text-decor=
ation-style:initial;text-decoration-color:initial"><font face=3D"monospace,=
 monospace">template&lt;class T&gt;</font></div><div style=3D"font-family:s=
ans-serif;background-color:rgb(255,255,255);text-decoration-style:initial;t=
ext-decoration-color:initial"><font face=3D"monospace, monospace">auto foo(=
T&amp;&amp; x)</font></div><div style=3D"font-family:sans-serif;background-=
color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:=
initial"><font face=3D"monospace, monospace">{</font></div><div style=3D"fo=
nt-family:sans-serif;background-color:rgb(255,255,255);text-decoration-styl=
e:initial;text-decoration-color:initial"><font face=3D"monospace, monospace=
">=C2=A0 return bar(fwd(x));=C2=A0 // but frankly I can&#39;t see a problem=
 with this either</font></div><div style=3D"font-family:sans-serif;backgrou=
nd-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-col=
or:initial"><font face=3D"monospace, monospace">}=C2=A0=C2=A0</font></div><=
br class=3D"gmail-Apple-interchange-newline"><br></font></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><br></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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/23af17ac-1c0e-4828-ade7-4b1ab00c601a%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/23af17ac-1c0e-=
4828-ade7-4b1ab00c601a%40isocpp.org</a>.<br>
</blockquote></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/CALvx3hZnpPGJ8gufQb%3Dm%3DnuT1GkkpCQX=
AuNSJ-wMFGSWrbPMAA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hZnpPGJ=
8gufQb%3Dm%3DnuT1GkkpCQXAuNSJ-wMFGSWrbPMAA%40mail.gmail.com</a>.<br />

--000000000000373de0056e2ffcab--

.


Author: mihailnajdenov@gmail.com
Date: Sat, 9 Jun 2018 02:08:02 -0700 (PDT)
Raw View
------=_Part_70682_2090287773.1528535282555
Content-Type: multipart/alternative;
 boundary="----=_Part_70683_187087185.1528535282557"

------=_Part_70683_187087185.1528535282557
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>
> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com
> <javascript:>> wrote:
>
>> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
>> >
>> > If one writes a function where he moves instead of forwarding
>> >
>> >
>> >     template< typename T >
>> >     void foo(T&& value)
>> >     {
>> >       vec.push_back(std::move(value));
>> >     }
>> > **//___^
>> > That will be *The Wrong Thing* to do.
>>
>> There's nothing wrong with it, as long as you actually want to move.
>>
>> > This is because one /lies against the interface /- T&& is a forwarding
>> > reference,/by definition/.
>> >
>> > Using "object passing", /prevents/ you to lie!
>>
>> There's no such thing as a forwarding reference in the language.
>
>
> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>


Interesting.

*Question*. Given T&& being a forwarding reference, if the type T is NOT
deduced but supplied by the user AND a reference collapsing still takes
place - can this still be considered "forwarding reference"

I imagine the answer is NO.


*However*. A real world example:

template<class fun>
class Fn;

template<class R, class... A>
class Fn<R(A...)>
{
  using F = R (*)(void*, A...);

  template<R (*f)(A...)>
  static R stub(void*, A&&... arg)
  {
    return (*f)(std::forward<A>(arg)...);
  }

  // ... other stubs to call member functions

public:
  // ...
  template<R (*f)(A...)>
  static Fn from() noexcept
  {
    return {nullptr, &stub<f>};
  }

  // NOT forward reference, however...yeah

  R operator ()(A&&... args) const
  {
    return _f(_p, std::forward<A>(args)...);
  }

public:
  void* _p;
  F _f;
};

In this example the operator() arguments will (need to) be "forwarding
references", though the type will not be deduced, but supplied by the user:

void func_cref(const int&) {}
void func_rref(int&&) {}

auto cb1 = Fn<void(const int&)>::from<&func_cref>();* //< void
Fn::operator(const int& &&) const --> *Fn::operator(const int&)
auto cb2 = Fn<void(int&&)>::from<&func_rref>();* //< void
Fn::operator(int&& &&**) const** --> *Fn::operator(const int&)

Effectively, we have "manual" "forwarding references".

Does the standard take these into account as such?



As Florian pointed out - metaprogramming could lead to a "forwarding
reference" "in the end".



I think that is an important question, not just for this proposal, but in
general, as teachability stand point for instance.

If we say *NO*, how can we explain the use of forward to a
beginner/intermediate?

If we say *YES*, then isn't the example in the standard somewhat incorrect
by claiming T&& is NOT a frw ref.


template <class T> struct A {
  template <class U>
    A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
                                // U&& is a forwarding reference.
  ...
};

Shouldn't the correct answer "it depends" (on the usage and instantiations
of the class)?


PS



>
>  Using
>> T&&, where T is a template argument, for forwarding is just one use
>> case, but there are also other. For example, this syntax can be used for
>> generalization so that you don't have to write multiple overloads for
>> different argument types.
>>
>> > See a similar post from the original discussion for detailed explanation
>> >
>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>
>> Using SFINAE to force users to explicitly move is a good approach, but I
>> don't think it is always necessary. If my foo function is called, say,
>> foo_move and is properly documented, there's no reason to force users to
>> explicitly call std::move on their end. Especially, if the user is me,
>> the implementer of foo_move.
>>
>> >     Forwarding and moving a value have a fundamental difference in
>> >     strength.
>> >     Forwarding does not move the value unless permitted by the program
>> >     (i.e.
>> >     the value is assumed to be unused afterwards) while std::move is
>> >     stronger and will move even lvalue. The fact that both may end up
>> >     moving
>> >     the value does not mean they are the same and should be expressed
>> the
>> >     same way. Being more explicit about the intent is beneficial to the
>> >     developer, experienced or junior.
>> >
>> > Question is what is the original intend? And actually the intend in
>> both
>> > cases is to give the object away.
>>
>> That's from the function caller's perspective. And as far as the caller
>> is concerned, if you want to move, you use std::move. You never use
>> std::forward to move a value.
>>
>> As a function implementer (or, more accurately, receiver of the function
>> arguments), you can have different intentions wrt. the arguments. Some
>> of the arguments you may move, others forward, thirds modify or copy. My
>> point is that the compiler is not able and should not be given liberty
>> to decide which behavior to apply in each case. And the end code will
>> have better quality if this intent is apparent.
>>
>> > About the "ugliness".
>> >
>> > Well, I really hoped a simple && would do the trick, but it does clash
>> > with the binary operator && and I see no way around that.
>> >
>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>> > passin.
>>
>> These don't look any better to me, sorry. Ignoring for a moment that I
>> don't like the idea to begin with, I would prefer a function-style
>> keyword instead of new obscure operators, especially 3 or more
>> characters long.
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>> .
>>
>

--
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/953e96fa-17e3-40a0-9f74-9a56765d2dce%40isocpp.org.

------=_Part_70683_187087185.1528535282557
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richa=
rd Smith 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"aut=
o"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:=
33 Andrey Semashev, &lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" h=
ref=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailt=
o=3D"e9O7oR40BQAJ">andrey....@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On 06/08/18 09:32, <a onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-o=
bfuscated-mailto=3D"e9O7oR40BQAJ">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%=
2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" onclick=3D"th=
is.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%2Fc%2B%2B=
draft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" href=3D"http://eel.is/=
c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=3D"nofollow">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><br></div><div>Interesting.=C2=A0</div><=
div><br></div><div><b>Question</b>. Given T&amp;&amp; being a forwarding re=
ference, if the type T is NOT deduced but supplied by the user AND a refere=
nce collapsing still takes place - can this still be considered &quot;<span=
 style=3D"display: inline !important; float: none; background-color: transp=
arent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;">forwarding r=
eference</span>&quot;</div><div><br></div><div>I imagine the answer is NO.<=
/div><div><br></div><div><br></div><div><b>However</b>. A real world exampl=
e:=C2=A0</div><div><font face=3D"courier new,monospace"></font><br></div><d=
iv><font face=3D"courier new,monospace">template&lt;class fun&gt;<br>class =
Fn;</font></div><div><font face=3D"courier new,monospace"><br></font></div>=
<div><font face=3D"courier new,monospace">template&lt;class R, class... A&g=
t;<br>class Fn&lt;R(A...)&gt;<br>{<br>=C2=A0 using F =3D R (*)(void*, A...)=
;</font><br></div><div><br></div><div><font face=3D"courier new,monospace">=
=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static R stub(void*, A&amp;&a=
mp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return (*f)(std::forward&lt;A=
&gt;(arg)...);<br>=C2=A0 }</font></div><div><font face=3D"courier new,monos=
pace"><div style=3D"background-color: transparent; border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;=
Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; tex=
t-align: left; text-decoration: none; text-indent: 0px; text-transform: non=
e; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"=
><font face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; ma=
rgin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; pad=
ding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"=
><br style=3D"background-attachment: scroll; background-clip: border-box; b=
ackground-color: transparent; background-image: none; background-origin: pa=
dding-box; background-position-x: 0%; background-position-y: 0%; background=
-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rg=
b(34, 34, 34); font-family: courier new,monospace; font-size: 13px; height:=
 auto; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top:=
 0px; min-width: 0px; overflow: visible; overflow-x: visible; overflow-y: v=
isible; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding=
-top: 0px;"></font></div><div style=3D"background-color: transparent; borde=
r-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-w=
idth: 0px; border-image-outset: 0; border-image-repeat: stretch; border-ima=
ge-slice: 100%; border-image-source: none; border-image-width: 1; border-le=
ft-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px;=
 border-right-color: rgb(34, 34, 34); border-right-style: none; border-righ=
t-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bo=
rder-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&a=
mp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-st=
yle: normal; font-variant: normal; font-weight: 400; letter-spacing: normal=
; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;=
 orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pa=
dding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; =
text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; =
word-spacing: 0px;"><font face=3D"courier new,monospace" style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; m=
argin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px;=
 padding-top: 0px;">=C2=A0 // ... other stubs to call member functions</fon=
t><br></div></font></div><div><font face=3D"courier new,monospace"><b></b><=
i></i><u></u><sub></sub><sup></sup><strike></strike><br></font></div><div><=
font face=3D"courier new,monospace">public:</font></div><div><font face=3D"=
courier new,monospace">=C2=A0 // ...</font></div><div><font face=3D"courier=
 new,monospace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static Fn fro=
m() noexcept<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;stub&l=
t;f&gt;};<br>=C2=A0 }</font></div><div><font face=3D"courier new,monospace"=
>=C2=A0=C2=A0</font></div><div><font face=3D"courier new,monospace">=C2=A0 =
// NOT forward reference, however...yeah</font></div><div><font face=3D"cou=
rier new,monospace"><br></font></div><div><font face=3D"courier new,monospa=
ce">=C2=A0 R operator ()(A&amp;&amp;... args) const<br>=C2=A0 {<br>=C2=A0 =
=C2=A0 return _f(_p, std::forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></d=
iv><div><font face=3D"courier new,monospace"><br></font></div><div><font fa=
ce=3D"courier new,monospace">public:<br>=C2=A0 void* _p;<br>=C2=A0 F _f;<br=
>};</font><br></div><div><font face=3D"courier new,monospace"></font><br></=
div><div>In this example the operator() arguments will (need to) be &quot;f=
orwarding references&quot;, though the type will not be deduced, but suppli=
ed by the user:</div><div><font face=3D"courier new,monospace"></font><br><=
/div><div><font face=3D"courier new,monospace">void func_cref(const int&amp=
;) {}</font></div><div><span style=3D"text-align: left; color: rgb(34, 34, =
34); text-transform: none; text-indent: 0px; letter-spacing: normal; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; text=
-decoration: none; word-spacing: 0px; display: inline !important; white-spa=
ce: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgr=
ound-color: transparent;"><font face=3D"courier new,monospace">void func_rr=
ef(int&amp;&amp;) {}</font></span><b></b><i></i><u></u><sub></sub><sup></su=
p><strike></strike><br></div><div><b></b><i></i><u></u><sub></sub><sup></su=
p><strike></strike><font face=3D"courier new,monospace"></font><br></div><d=
iv><font face=3D"courier new,monospace">auto cb1 =3D Fn&lt;void(const int&a=
mp;)&gt;::from&lt;&amp;<span style=3D"text-align: left; color: rgb(34, 34, =
34); text-transform: none; text-indent: 0px; letter-spacing: normal; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; text=
-decoration: none; word-spacing: 0px; display: inline !important; white-spa=
ce: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgr=
ound-color: transparent;">func_cref</span>&gt;();<i> //&lt; void Fn::operat=
or(<span style=3D"text-align: left; color: rgb(34, 34, 34); text-transform:=
 none; text-indent: 0px; letter-spacing: normal; font-family: courier new,m=
onospace; font-size: 13px; font-variant: normal; font-weight: 400; text-dec=
oration: none; word-spacing: 0px; display: inline !important; white-space: =
normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background=
-color: transparent;">const int&amp; &amp;&amp;</span>) const --&gt; </i><s=
pan style=3D"display: inline !important; float: none; background-color: tra=
nsparent; color: rgb(34, 34, 34); font-family: courier new,monospace; font-=
size: 13px; font-style: italic; font-variant: normal; font-weight: 400; let=
ter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; t=
ext-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whit=
e-space: normal; word-spacing: 0px;">Fn::operator(</span><span style=3D"bac=
kground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-sty=
le: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bord=
er-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34=
, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34=
); display: inline; float: none; font-family: courier new,monospace; font-s=
ize: 13px; font-style: italic; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">const int&amp;</span><span style=3D"d=
isplay: inline !important; float: none; background-color: transparent; colo=
r: rgb(34, 34, 34); font-family: courier new,monospace; font-size: 13px; fo=
nt-style: italic; font-variant: normal; font-weight: 400; letter-spacing: n=
ormal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0p=
x; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norma=
l; word-spacing: 0px;">)</span></font></div><div><font face=3D"courier new,=
monospace"><span style=3D"text-align: left; color: rgb(34, 34, 34); text-tr=
ansform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; text-decoration:=
 none; word-spacing: 0px; display: inline !important; white-space: normal; =
orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: =
transparent;">auto cb2 =3D Fn&lt;void(int&amp;&amp;)&gt;::from&lt;&amp;</sp=
an><span style=3D"background-color: transparent; border-bottom-color: rgb(3=
4, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-ima=
ge-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; borde=
r-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34,=
 34); border-left-style: none; border-left-width: 0px; border-right-color: =
rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-=
top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; =
color: rgb(34, 34, 34); display: inline; float: none; font-family: &amp;quo=
t;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px=
; font-style: normal; font-variant: normal; font-weight: 400; letter-spacin=
g: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-=
top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
 normal; word-spacing: 0px;">func_<span style=3D"text-align: left; color: r=
gb(34, 34, 34); text-transform: none; text-indent: 0px; letter-spacing: nor=
mal; font-size: 13px; font-style: normal; font-variant: normal; font-weight=
: 400; text-decoration: none; word-spacing: 0px; display: inline !important=
; white-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: =
0px; background-color: transparent;">rref</span></span><span style=3D"text-=
align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px=
; letter-spacing: normal; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; text-decoration: none; word-spacing: 0px; displ=
ay: inline !important; white-space: normal; orphans: 2; float: none; -webki=
t-text-stroke-width: 0px; background-color: transparent;">&gt;();<i><span s=
tyle=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none; tex=
t-indent: 0px; letter-spacing: normal; font-family: courier new,monospace; =
font-size: 13px; font-variant: normal; font-weight: 400; text-decoration: n=
one; word-spacing: 0px; display: inline !important; white-space: normal; or=
phans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: tr=
ansparent;"> //&lt; void Fn::operator(</span><span style=3D"margin: 0px; pa=
dding: 0px; border: 0px rgb(34, 34, 34); border-image: none; text-align: le=
ft; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-=
spacing: normal; font-family: courier new,monospace; font-size: 13px; font-=
variant: normal; font-weight: 400; text-decoration: none; word-spacing: 0px=
; display: inline; white-space: normal; orphans: 2; float: none; -webkit-te=
xt-stroke-width: 0px; background-color: transparent;">int&amp;&amp; &amp;&a=
mp;</span></i><span style=3D"text-align: left; color: rgb(34, 34, 34); text=
-transform: none; text-indent: 0px; letter-spacing: normal; font-family: co=
urier new,monospace; font-size: 13px; font-variant: normal; font-weight: 40=
0; text-decoration: none; word-spacing: 0px; display: inline !important; wh=
ite-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px;=
 background-color: transparent;"><i>) const</i><i> --&gt; </i><span style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); display: inline; float: none; font-family: courier new,monospace;=
 font-size: 13px; font-style: italic; font-variant: normal; font-weight: 40=
0; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-rig=
ht: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0p=
x; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration:=
 none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0=
px; white-space: normal; word-spacing: 0px;">Fn::operator(</span><span styl=
e=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); b=
order-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0;=
 border-image-repeat: stretch; border-image-slice: 100%; border-image-sourc=
e: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-=
left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 3=
4); border-right-style: none; border-right-width: 0px; border-top-color: rg=
b(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34=
, 34, 34); display: inline; float: none; font-family: courier new,monospace=
; font-size: 13px; font-style: italic; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0=
px; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;">const int&amp;</span><span st=
yle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); display: inline; float: none; font-family: courier new,monospa=
ce; font-size: 13px; font-style: italic; font-variant: normal; font-weight:=
 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decorati=
on: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width=
: 0px; white-space: normal; word-spacing: 0px;">)</span></span></span></fon=
t><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><di=
v><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><font face=3D=
"courier new,monospace"></font><b></b><i></i><u></u><sub></sub><sup></sup><=
strike></strike><i></i><b></b><i></i><u></u><sub></sub><sup></sup><strike><=
/strike><br></div><div>Effectively, we have &quot;manual&quot; &quot;forwar=
ding references&quot;.</div><div><br></div><div>Does the standard take thes=
e into account as such?=C2=A0</div><div><br></div><div><br></div><div><br><=
/div><div>As <span style=3D"display: inline !important; float: none; backgr=
ound-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&q=
uot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal;=
 font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;">Florian pointed out - metaprogramming could lead to a &quot;forwardin=
g reference&quot; &quot;in the end&quot;.=C2=A0</span><span style=3D"displa=
y: inline !important; float: none; background-color: transparent; color: rg=
b(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-se=
rif; font-size: 13px; font-style: normal; font-variant: normal; font-weight=
: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoratio=
n: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width:=
 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div><span =
style=3D"display: inline !important; float: none; background-color: transpa=
rent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norm=
al; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></=
div><div><span style=3D"display: inline !important; float: none; background=
-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; fon=
t-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; te=
xt-align: left; text-decoration: none; text-indent: 0px; text-transform: no=
ne; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;=
"><br></span></div><div><span style=3D"display: inline !important; float: n=
one; background-color: transparent; color: rgb(34, 34, 34); font-family: &q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-sty=
le: normal; font-variant: normal; font-weight: 400; letter-spacing: normal;=
 orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; tex=
t-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wor=
d-spacing: 0px;"><br></span></div><div><span style=3D"display: inline !impo=
rtant; float: none; background-color: transparent; color: rgb(34, 34, 34); =
font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size:=
 13px; font-style: normal; font-variant: normal; font-weight: 400; letter-s=
pacing: normal; orphans: 2; text-align: left; text-decoration: none; text-i=
ndent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spa=
ce: normal; word-spacing: 0px;">I think that is an important question, not =
just for this proposal, but in general, as teachability stand point for ins=
tance.=C2=A0</span></div><div><span style=3D"display: inline !important; fl=
oat: none; background-color: transparent; color: rgb(34, 34, 34); font-fami=
ly: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; fo=
nt-style: normal; font-variant: normal; font-weight: 400; letter-spacing: n=
ormal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0p=
x; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norma=
l; word-spacing: 0px;"><br></span></div><div><span style=3D"display: inline=
 !important; float: none; background-color: transparent; color: rgb(34, 34,=
 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">If we say <b>NO</b>, how can we expla=
in the use of forward to a beginner/intermediate?</span></div><div><span st=
yle=3D"display: inline !important; float: none; background-color: transpare=
nt; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></di=
v><div><span style=3D"display: inline !important; float: none; background-c=
olor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-=
variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text=
-align: left; text-decoration: none; text-indent: 0px; text-transform: none=
; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=
If we say <b>YES</b>, then isn&#39;t the example in the standard somewhat i=
ncorrect by claiming T&amp;&amp; is NOT a frw ref.=C2=A0</span></div><div><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></sp=
an></div><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text=
-transform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px=
; font-style: normal; font-variant: normal; font-weight: 400; text-decorati=
on: none; word-spacing: 0px; display: inline !important; white-space: norma=
l; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-colo=
r: transparent;"><font face=3D"courier new,monospace"></font><br></span></d=
iv><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-trans=
form: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; font=
-variant: normal; word-spacing: 0px; display: inline !important; white-spac=
e: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgro=
und-color: transparent;"><font face=3D"courier new,monospace"><span style=
=3D"text-align: justify; color: rgb(0, 0, 0); text-transform: none; line-he=
ight: 17.33px; text-indent: 0px; letter-spacing: normal; font-size: 13.33px=
; font-style: normal; font-variant: normal; font-weight: 400; text-decorati=
on: none; word-spacing: 0px; display: inline !important; white-space: pre; =
orphans: 2; float: none; -webkit-text-stroke-width: 0px; background-color: =
transparent;">template &lt;class T&gt; struct A {<br>=C2=A0 template &lt;cl=
ass U&gt;<br>=C2=A0=C2=A0=C2=A0 A(T&amp;&amp;, U&amp;&amp;, int*);=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 </span><span class=3D"comment=
" style=3D"text-align: justify; color: rgb(0, 0, 0); text-transform: none; =
text-indent: 0px; letter-spacing: normal; font-size: 13.33px; font-style: i=
talic; font-variant: normal; font-weight: 400; text-decoration: none; word-=
spacing: 0px; white-space: pre; orphans: 2; -webkit-text-stroke-width: 0px;=
 background-color: transparent;">// #1: <span class=3D"tcode_in_codeblock" =
style=3D"font-style: normal;">T&amp;&amp;</span> is not a forwarding refere=
nce.<br></span><span style=3D"text-align: justify; color: rgb(0, 0, 0); tex=
t-transform: none; line-height: 17.33px; text-indent: 0px; letter-spacing: =
normal; font-size: 13.33px; font-style: normal; font-variant: normal; font-=
weight: 400; text-decoration: none; word-spacing: 0px; display: inline !imp=
ortant; white-space: pre; orphans: 2; float: none; -webkit-text-stroke-widt=
h: 0px; background-color: transparent;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 </span><span class=3D"comment" style=3D"text-align: justify; color: rgb=
(0, 0, 0); text-transform: none; text-indent: 0px; letter-spacing: normal; =
font-size: 13.33px; font-style: italic; font-variant: normal; font-weight: =
400; text-decoration: none; word-spacing: 0px; white-space: pre; orphans: 2=
; -webkit-text-stroke-width: 0px; background-color: transparent;">// <span =
class=3D"tcode_in_codeblock" style=3D"font-style: normal;">U&amp;&amp;</spa=
n> is a forwarding reference.<br></span><span style=3D"text-align: justify;=
 color: rgb(0, 0, 0); text-transform: none; line-height: 17.33px; text-inde=
nt: 0px; letter-spacing: normal; font-size: 13.33px; font-style: normal; fo=
nt-variant: normal; font-weight: 400; text-decoration: none; word-spacing: =
0px; display: inline !important; white-space: pre; orphans: 2; float: none;=
 -webkit-text-stroke-width: 0px; background-color: transparent;">=C2=A0 ...=
</span><span class=3D"comment" style=3D"text-align: justify; color: rgb(0, =
0, 0); text-transform: none; text-indent: 0px; letter-spacing: normal; font=
-size: 13.33px; font-style: italic; font-variant: normal; font-weight: 400;=
 text-decoration: none; word-spacing: 0px; white-space: pre; orphans: 2; -w=
ebkit-text-stroke-width: 0px; background-color: transparent;"><br></span><s=
pan style=3D"text-align: justify; color: rgb(0, 0, 0); text-transform: none=
; line-height: 17.33px; text-indent: 0px; letter-spacing: normal; font-size=
: 13.33px; font-style: normal; font-variant: normal; font-weight: 400; text=
-decoration: none; word-spacing: 0px; display: inline !important; white-spa=
ce: pre; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgroun=
d-color: transparent;">};</span></font><b></b><i></i><u></u><sub></sub><sup=
></sup><strike></strike><br></span></div><div><span style=3D"display: inlin=
e !important; float: none; background-color: transparent; color: rgb(34, 34=
, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; fon=
t-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; l=
etter-spacing: normal; orphans: 2; text-align: left; text-decoration: none;=
 text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; wh=
ite-space: normal; word-spacing: 0px;"><b></b><i></i><u></u><sub></sub><sup=
></sup><strike></strike><font face=3D"courier new,monospace"></font><br></s=
pan></div><div><span style=3D"display: inline !important; float: none; back=
ground-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans:=
 2; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;">Shouldn&#39;t the correct answer &quot;it depends&quot; (on the usa=
ge and instantiations of the class)?=C2=A0</span></div><div><span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div>=
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></s=
pan></div><div><span style=3D"display: inline !important; float: none; back=
ground-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans:=
 2; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing=
: 0px;">PS</span></div><div><span style=3D"display: inline !important; floa=
t: none; background-color: transparent; color: rgb(34, 34, 34); font-family=
: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font=
-style: normal; font-variant: normal; font-weight: 400; letter-spacing: nor=
mal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px;=
 text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal;=
 word-spacing: 0px;"></span></div><div><b></b><i></i><u></u><sub></sub><sup=
></sup><strike></strike><b></b><b></b><i></i><u></u><sub></sub><sup></sup><=
strike></strike><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"auto"><div dir=3D"auto"></div><div dir=3D"auto"><b=
r></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.=
org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" target=
=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"e9O7oR40BQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"e9O7oR40BQAJ">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800=
-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad2=
77-7800-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" href=3D"https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-=
35cc-16d11e1c65d9%40gmail.com" target=3D"_blank" rel=3D"nofollow">https://g=
roups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/095ad277-7800=
-53e2-<wbr>35cc-16d11e1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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/953e96fa-17e3-40a0-9f74-9a56765d2dce%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/953e96fa-17e3-40a0-9f74-9a56765d2dce=
%40isocpp.org</a>.<br />

------=_Part_70683_187087185.1528535282557--

------=_Part_70682_2090287773.1528535282555--

.


Author: mihailnajdenov@gmail.com
Date: Sat, 9 Jun 2018 02:14:24 -0700 (PDT)
Raw View
------=_Part_72835_452938654.1528535664450
Content-Type: multipart/alternative;
 boundary="----=_Part_72836_217948924.1528535664453"

------=_Part_72836_217948924.1528535664453
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>
> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com
> <javascript:>> wrote:
>
>> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
>> >
>> > If one writes a function where he moves instead of forwarding
>> >
>> >
>> >     template< typename T >
>> >     void foo(T&& value)
>> >     {
>> >       vec.push_back(std::move(value));
>> >     }
>> > **//___^
>> > That will be *The Wrong Thing* to do.
>>
>> There's nothing wrong with it, as long as you actually want to move.
>>
>> > This is because one /lies against the interface /- T&& is a forwarding
>> > reference,/by definition/.
>> >
>> > Using "object passing", /prevents/ you to lie!
>>
>> There's no such thing as a forwarding reference in the language.
>
>
> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>

Interesting.

*Question*. Given T&& being a forwarding reference, if the type T is NOT
deduced but supplied by the user AND a reference collapsing still takes
place - can this still be considered "forwarding reference"

I imagine the answer is NO.


*However*. A real world example:

template<class fun>
class Fn;

template<class R, class... A>
class Fn<R(A...)>
{
  using F = R (*)(void*, A...);

  template<R (*f)(A...)>
  static R stub(void*, A&&... arg)
  {
    return (*f)(std::forward<A>(arg)...);
  }

  // ... other stubs to call member functions

public:
  // ...
  template<R (*f)(A...)>
  static Fn from() noexcept
  {
    return {nullptr, &stub<f>};
  }

  // NOT forward reference, however...yeah

  R operator ()(A&&... args) const
  {
    return _f(_p, std::forward<A>(args)...);
  }

public:
  void* _p;
  F _f;
};

In this example the operator() arguments will (need to) be "forwarding
references", though the type will not be deduced, but supplied by the user:

void func_cref(const int&) {}
void func_rref(int&&) {}

auto cb1 = Fn<void(const int&)>::from<&func_cref>();* //< void
Fn::operator(const int& &&) const --> *Fn::operator(const int&)
auto cb2 = Fn<void(int&&)>::from<&func_rref>();* //< void
Fn::operator(int&& &&**) const** --> *Fn::operator(int&&)

Effectively, we have "manual" "forwarding references".

Does the standard take these into account as such?



As Florian pointed out - metaprogramming could lead to a "forwarding
reference" "in the end".



I think that is an important question, not just for this proposal, but in
general, as teachability stand point for instance.

If we say *NO*, how can we explain the correct and advised use of forward
to a beginner/intermediate?

If we say *YES*, then isn't the example in the standard somewhat incorrect
by claiming T&& is NOT a frw ref.

template <class T> struct A {
  template <class U>
    A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
                                // U&& is a forwarding reference.
  ...
};

Shouldn't the correct answer "it depends" (on the usage and instantiations
of the class)?



P.S

Currently the cppreference.com explicitly talks about argument deduction
*Reference collapsing*
*...*
*(This, along with special rules for template argument deduction when T&&
is used in a function template, forms the rules that make std::forward
possible.) *



>
>  Using
>> T&&, where T is a template argument, for forwarding is just one use
>> case, but there are also other. For example, this syntax can be used for
>> generalization so that you don't have to write multiple overloads for
>> different argument types.
>>
>> > See a similar post from the original discussion for detailed explanation
>> >
>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>
>> Using SFINAE to force users to explicitly move is a good approach, but I
>> don't think it is always necessary. If my foo function is called, say,
>> foo_move and is properly documented, there's no reason to force users to
>> explicitly call std::move on their end. Especially, if the user is me,
>> the implementer of foo_move.
>>
>> >     Forwarding and moving a value have a fundamental difference in
>> >     strength.
>> >     Forwarding does not move the value unless permitted by the program
>> >     (i.e.
>> >     the value is assumed to be unused afterwards) while std::move is
>> >     stronger and will move even lvalue. The fact that both may end up
>> >     moving
>> >     the value does not mean they are the same and should be expressed
>> the
>> >     same way. Being more explicit about the intent is beneficial to the
>> >     developer, experienced or junior.
>> >
>> > Question is what is the original intend? And actually the intend in
>> both
>> > cases is to give the object away.
>>
>> That's from the function caller's perspective. And as far as the caller
>> is concerned, if you want to move, you use std::move. You never use
>> std::forward to move a value.
>>
>> As a function implementer (or, more accurately, receiver of the function
>> arguments), you can have different intentions wrt. the arguments. Some
>> of the arguments you may move, others forward, thirds modify or copy. My
>> point is that the compiler is not able and should not be given liberty
>> to decide which behavior to apply in each case. And the end code will
>> have better quality if this intent is apparent.
>>
>> > About the "ugliness".
>> >
>> > Well, I really hoped a simple && would do the trick, but it does clash
>> > with the binary operator && and I see no way around that.
>> >
>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>> > passin.
>>
>> These don't look any better to me, sorry. Ignoring for a moment that I
>> don't like the idea to begin with, I would prefer a function-style
>> keyword instead of new obscure operators, especially 3 or more
>> characters long.
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>> .
>>
>

--
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/284f098b-471e-4122-a26a-f58e0d8871d9%40isocpp.org.

------=_Part_72836_217948924.1528535664453
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richa=
rd Smith 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"aut=
o"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:=
33 Andrey Semashev, &lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" h=
ref=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailt=
o=3D"e9O7oR40BQAJ">andrey....@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On 06/08/18 09:32, <a onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-o=
bfuscated-mailto=3D"e9O7oR40BQAJ">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%=
2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" onclick=3D"th=
is.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%2Fc%2B%2B=
draft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" href=3D"http://eel.is/=
c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=3D"nofollow">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><div style=3D"background-color: transpar=
ent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;qu=
ot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13p=
x; font-style: normal; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin=
-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-ind=
ent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space=
: normal; word-spacing: 0px;">Interesting.=C2=A0</div><div style=3D"backgro=
und-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); f=
ont-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-se=
rif; font-size: 13px; font-style: normal; font-variant: normal; font-weight=
: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decorat=
ion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-widt=
h: 0px; white-space: normal; word-spacing: 0px;"><br style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><b style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">Qu=
estion</b>. Given T&amp;&amp; being a forwarding reference, if the type T i=
s NOT deduced but supplied by the user AND a reference collapsing still tak=
es place - can this still be considered &quot;<span style=3D"background-col=
or: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); display:=
 inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helv=
etica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varia=
nt: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; m=
argin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px;">forwarding reference</span>&quot;</div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br style=3D"=
border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bot=
tom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; borde=
r-image-slice: 100%; border-image-source: none; border-image-width: 1; bord=
er-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width:=
 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border=
-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: non=
e; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; marg=
in-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddi=
ng-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><=
/div><div style=3D"background-color: transparent; border-bottom-color: rgb(=
34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-im=
age-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bord=
er-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34=
, 34); border-left-style: none; border-left-width: 0px; border-right-color:=
 rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border=
-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px;=
 color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;H=
elvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-va=
riant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px=
; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding=
-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text=
-align: left; text-decoration: none; text-indent: 0px; text-transform: none=
; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=
I imagine the answer is NO.</div><div style=3D"background-color: transparen=
t; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-=
bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bo=
rder-image-slice: 100%; border-image-source: none; border-image-width: 1; b=
order-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wid=
th: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bor=
der-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: =
none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot=
;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: r=
gb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; =
margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px;=
 padding-right: 0px; padding-top: 0px;"></div><div style=3D"background-colo=
r: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-fami=
ly: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; fon=
t-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; l=
etter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; p=
adding-right: 0px; padding-top: 0px; text-align: left; text-decoration: non=
e; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; =
white-space: normal; word-spacing: 0px;"><br style=3D"border-bottom-color: =
rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; borde=
r-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; =
border-image-source: none; border-image-width: 1; border-left-color: rgb(34=
, 34, 34); border-left-style: none; border-left-width: 0px; border-right-co=
lor: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bo=
rder-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: =
0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"ba=
ckground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-b=
ottom-style: none; border-bottom-width: 0px; border-image-outset: 0; border=
-image-repeat: stretch; border-image-slice: 100%; border-image-source: none=
; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-st=
yle: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bor=
der-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 3=
4, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 3=
4); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; m=
argin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding=
-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-de=
coration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke=
-width: 0px; white-space: normal; word-spacing: 0px;"><b style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">However</b=
>. A real world example:=C2=A0</div><div style=3D"background-color: transpa=
rent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bord=
er-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch;=
 border-image-slice: 100%; border-image-source: none; border-image-width: 1=
; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-=
width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; =
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-styl=
e: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;q=
uot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margi=
n-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-rig=
ht: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-in=
dent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spac=
e: normal; word-spacing: 0px;"><font face=3D"courier new,monospace" style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"></font><br style=3D"border-bottom-color: r=
gb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border=
-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; b=
order-image-source: none; border-image-width: 1; border-left-color: rgb(34,=
 34, 34); border-left-style: none; border-left-width: 0px; border-right-col=
or: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bor=
der-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0=
px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"bac=
kground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-sty=
le: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bord=
er-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34=
, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34=
); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; ma=
rgin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D"courier =
new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;">template&lt;class fun&=
gt;<br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-heig=
ht: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin=
-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padd=
ing-top: 0px;">class Fn;</font></div><div style=3D"background-color: transp=
arent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;=
quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 1=
3px; font-style: normal; font-variant: normal; font-weight: 400; letter-spa=
cing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; marg=
in-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-ri=
ght: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-i=
ndent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-spa=
ce: normal; word-spacing: 0px;"><font face=3D"courier new,monospace" style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"><br style=3D"border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;"></font></div><div style=3D"bac=
kground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-sty=
le: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bord=
er-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34=
, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34=
); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; ma=
rgin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D"courier =
new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;">template&lt;class R, c=
lass... A&gt;<br style=3D"border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34);=
 line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0=
px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px;">class Fn&lt;R(A...)&gt;<br style=3D"border-bottom-=
color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px=
; border-image-outset: 0; border-image-repeat: stretch; border-image-slice:=
 100%; border-image-source: none; border-image-width: 1; border-left-color:=
 rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-r=
ight-color: rgb(34, 34, 34); border-right-style: none; border-right-width: =
0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-=
width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px=
; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{<br style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=
=C2=A0 using F =3D R (*)(void*, A...);</font><br style=3D"border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; m=
argin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br style=3D"bo=
rder-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-botto=
m-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-=
image-slice: 100%; border-image-source: none; border-image-width: 1; border=
-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-r=
ight-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none;=
 border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding=
-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></d=
iv><div style=3D"background-color: transparent; border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Hel=
vetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><f=
ont face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
 border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=
=C2=A0 template&lt;R (*f)(A...)&gt;<br style=3D"border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-lef=
t: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 static R stub(void*, =
A&amp;&amp;... arg)<br style=3D"border-bottom-color: rgb(34, 34, 34); borde=
r-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bor=
der-image-repeat: stretch; border-image-slice: 100%; border-image-source: n=
one; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left=
-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); =
border-right-style: none; border-right-width: 0px; border-top-color: rgb(34=
, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34=
, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-=
right: 0px; padding-top: 0px;">=C2=A0 {<br style=3D"border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-=
left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding=
-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0=C2=A0=C2=A0 retur=
n (*f)(std::forward&lt;A&gt;(arg)...);<br style=3D"border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 }</font></div><div=
 style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: r=
gb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&=
amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: no=
rmal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-=
left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: =
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: l=
eft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit=
-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font fac=
e=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><div styl=
e=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddi=
ng-right: 0px; padding-top: 0px;"><font face=3D"courier new,monospace" styl=
e=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddi=
ng-right: 0px; padding-top: 0px;"><br style=3D"background-color: transparen=
t; background-image: none; background-repeat: repeat; border-bottom-color: =
rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); font-family: courier new,m=
onospace; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-rig=
ht: 0px; margin-top: 0px; min-height: auto; min-width: 0px; overflow: visib=
le; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px;"></font></div><div style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"><font face=3D"courier new,monospace" style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;">=C2=A0 // ... other stubs to call member f=
unctions</font><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-sty=
le: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bord=
er-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34=
, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34=
); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px;"></div></font></div><div style=3D"background-colo=
r: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-fami=
ly: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; fon=
t-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; l=
etter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; p=
adding-right: 0px; padding-top: 0px; text-align: left; text-decoration: non=
e; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; =
white-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospac=
e" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none=
; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: st=
retch; border-image-slice: 100%; border-image-source: none; border-image-wi=
dth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border=
-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: =
none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-to=
p-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px;=
 margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px=
; padding-right: 0px; padding-top: 0px;"><b style=3D"border-bottom-color: r=
gb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border=
-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; b=
order-image-source: none; border-image-width: 1; border-left-color: rgb(34,=
 34, 34); border-left-style: none; border-left-width: 0px; border-right-col=
or: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bor=
der-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0=
px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px;"></b><i style=3D"border-=
bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-wid=
th: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image=
-slice: 100%; border-image-source: none; border-image-width: 1; border-left=
-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; b=
order-right-color: rgb(34, 34, 34); border-right-style: none; border-right-=
width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bord=
er-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></i><u s=
tyle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bo=
rder-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretc=
h; border-image-slice: 100%; border-image-source: none; border-image-width:=
 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-lef=
t-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none=
; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-st=
yle: none; border-top-width: 0px; color: rgb(34, 34, 34); line-height: norm=
al; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0p=
x; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top:=
 0px;"></u><sub style=3D"border-bottom-color: rgb(34, 34, 34); border-botto=
m-style: none; border-bottom-width: 0px; border-image-outset: 0; border-ima=
ge-repeat: stretch; border-image-slice: 100%; border-image-source: none; bo=
rder-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style:=
 none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-=
right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 3=
4); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padd=
ing-left: 0px; padding-right: 0px; padding-top: 0px;"></sub><sup style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right=
: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-rig=
ht: 0px; padding-top: 0px;"></sup><strike style=3D"border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;=
 padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px;"></strike><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bot=
tom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-i=
mage-repeat: stretch; border-image-slice: 100%; border-image-source: none; =
border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-styl=
e: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); borde=
r-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34,=
 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34)=
; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px;"></font></div><div style=3D"background-color: tran=
sparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; b=
order-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stret=
ch; border-image-slice: 100%; border-image-source: none; border-image-width=
: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-le=
ft-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: non=
e; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-s=
tyle: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &am=
p;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size:=
 13px; font-style: normal; font-variant: normal; font-weight: 400; letter-s=
pacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ma=
rgin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-=
right: 0px; padding-top: 0px; text-align: left; text-decoration: none; text=
-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-s=
pace: normal; word-spacing: 0px;"><font face=3D"courier new,monospace" styl=
e=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddi=
ng-right: 0px; padding-top: 0px;">public:</font></div><div style=3D"backgro=
und-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); f=
ont-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-se=
rif; font-size: 13px; font-style: normal; font-variant: normal; font-weight=
: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decorat=
ion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-widt=
h: 0px; white-space: normal; word-spacing: 0px;"><font face=3D"courier new,=
monospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-sty=
le: none; border-bottom-width: 0px; border-image-outset: 0; border-image-re=
peat: stretch; border-image-slice: 100%; border-image-source: none; border-=
image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none=
; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right=
-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); b=
order-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-le=
ft: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-l=
eft: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 // ...</font></div>=
<div style=3D"background-color: transparent; border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvet=
ica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font=
 face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=
=A0 template&lt;R (*f)(A...)&gt;<br style=3D"border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0=
px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: =
0px; padding-right: 0px; padding-top: 0px;">=C2=A0 static Fn from() noexcep=
t<br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-height=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px;">=C2=A0 {<br style=3D"border-bottom-color: rgb(34, 34, 34); bor=
der-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; b=
order-image-repeat: stretch; border-image-slice: 100%; border-image-source:=
 none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-le=
ft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34)=
; border-right-style: none; border-right-width: 0px; border-top-color: rgb(=
34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, =
34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;">=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;s=
tub&lt;f&gt;};<br style=3D"border-bottom-color: rgb(34, 34, 34); border-bot=
tom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-i=
mage-repeat: stretch; border-image-slice: 100%; border-image-source: none; =
border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-styl=
e: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); borde=
r-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34,=
 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34)=
; line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px;">=C2=A0 }</font></div><div style=3D"background-col=
or: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-fam=
ily: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; =
padding-right: 0px; padding-top: 0px; text-align: left; text-decoration: no=
ne; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px;=
 white-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospa=
ce" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: non=
e; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: s=
tretch; border-image-slice: 100%; border-image-source: none; border-image-w=
idth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; borde=
r-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style:=
 none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-t=
op-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px=
; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0p=
x; padding-right: 0px; padding-top: 0px;">=C2=A0=C2=A0</font></div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D=
"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 // NOT=
 forward reference, however...yeah</font></div><div style=3D"background-col=
or: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-fam=
ily: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; =
padding-right: 0px; padding-top: 0px; text-align: left; text-decoration: no=
ne; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px;=
 white-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospa=
ce" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: non=
e; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: s=
tretch; border-image-slice: 100%; border-image-source: none; border-image-w=
idth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; borde=
r-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style:=
 none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-t=
op-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px=
; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0p=
x; padding-right: 0px; padding-top: 0px;"><br style=3D"border-bottom-color:=
 rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bord=
er-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%;=
 border-image-source: none; border-image-width: 1; border-left-color: rgb(3=
4, 34, 34); border-left-style: none; border-left-width: 0px; border-right-c=
olor: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; b=
order-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width:=
 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padd=
ing-left: 0px; padding-right: 0px; padding-top: 0px;"></font></div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D=
"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 R oper=
ator ()(A&amp;&amp;... args) const<br style=3D"border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 {<br style=3D"border-b=
ottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-widt=
h: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-=
slice: 100%; border-image-source: none; border-image-width: 1; border-left-=
color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bo=
rder-right-color: rgb(34, 34, 34); border-right-style: none; border-right-w=
idth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; borde=
r-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 =
=C2=A0 return _f(_p, std::forward&lt;A&gt;(args)...);<br style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 }</=
font></div><div style=3D"background-color: transparent; border-bottom-color=
: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bor=
der-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%=
; border-image-source: none; border-image-width: 1; border-left-color: rgb(=
34, 34, 34); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; =
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width=
: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;=
quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; f=
ont-variant: normal; font-weight: 400; letter-spacing: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;"><font face=3D"courier new,monospace" style=3D"border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px;"><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
 border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-h=
eight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></font></div><div style=3D"background-color: transparent;=
 border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bo=
ttom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bord=
er-image-slice: 100%; border-image-source: none; border-image-width: 1; bor=
der-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width=
: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; borde=
r-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: no=
ne; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;A=
rial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top=
: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0=
px; padding-top: 0px; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;"><font face=3D"courier new,monospace" style=3D"bor=
der-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom=
-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-i=
mage-slice: 100%; border-image-source: none; border-image-width: 1; border-=
left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0p=
x; border-right-color: rgb(34, 34, 34); border-right-style: none; border-ri=
ght-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; =
border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px;">public:<br style=3D"border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 void* _p;<br style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=
=C2=A0 F _f;<br style=3D"border-bottom-color: rgb(34, 34, 34); border-botto=
m-style: none; border-bottom-width: 0px; border-image-outset: 0; border-ima=
ge-repeat: stretch; border-image-slice: 100%; border-image-source: none; bo=
rder-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style:=
 none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-=
right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 3=
4); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); =
line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0p=
x; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: =
0px; padding-top: 0px;">};</font><br style=3D"border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"background=
-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-st=
yle: none; border-bottom-width: 0px; border-image-outset: 0; border-image-r=
epeat: stretch; border-image-slice: 100%; border-image-source: none; border=
-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: non=
e; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-righ=
t-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); =
border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font=
-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0=
px; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;"><font face=3D"courier new,mon=
ospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;"></font><br style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div=
 style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: r=
gb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&=
amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: no=
rmal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-=
left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: =
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: l=
eft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit=
-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">In this e=
xample the operator() arguments will (need to) be &quot;forwarding referenc=
es&quot;, though the type will not be deduced, but supplied by the user:</d=
iv><div style=3D"background-color: transparent; border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Hel=
vetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><f=
ont face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
 border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></=
font><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style=
: none; border-bottom-width: 0px; border-image-outset: 0; border-image-repe=
at: stretch; border-image-slice: 100%; border-image-source: none; border-im=
age-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; =
border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-s=
tyle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bor=
der-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-he=
ight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; marg=
in-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pa=
dding-top: 0px;"></div><div style=3D"background-color: transparent; border-=
bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-wid=
th: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image=
-slice: 100%; border-image-source: none; border-image-width: 1; border-left=
-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; b=
order-right-color: rgb(34, 34, 34); border-right-style: none; border-right-=
width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bord=
er-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp=
;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-styl=
e: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; =
margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; o=
rphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padd=
ing-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; te=
xt-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wo=
rd-spacing: 0px;"><font face=3D"courier new,monospace" style=3D"border-bott=
om-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: =
0px; border-image-outset: 0; border-image-repeat: stretch; border-image-sli=
ce: 100%; border-image-source: none; border-image-width: 1; border-left-col=
or: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; borde=
r-right-color: rgb(34, 34, 34); border-right-style: none; border-right-widt=
h: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-t=
op-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;">void func_cref(const int&amp;) {}</font></div><div style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"=
background-color: transparent; border-bottom-color: rgb(34, 34, 34); border=
-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bord=
er-image-repeat: stretch; border-image-slice: 100%; border-image-source: no=
ne; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-=
style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); b=
order-right-style: none; border-right-width: 0px; border-top-color: rgb(34,=
 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34,=
 34); display: inline; float: none; font-size: 13px; font-style: normal; fo=
nt-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; white=
-space: normal; word-spacing: 0px;"><font face=3D"courier new,monospace" st=
yle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pad=
ding-right: 0px; padding-top: 0px;">void func_rref(int&amp;&amp;) {}</font>=
</span><b style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
 border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-h=
eight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></b><i style=3D"border-bottom-color: rgb(34, 34, 34); bor=
der-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; b=
order-image-repeat: stretch; border-image-slice: 100%; border-image-source:=
 none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-le=
ft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34)=
; border-right-style: none; border-right-width: 0px; border-top-color: rgb(=
34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, =
34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"></i><u style=3D"border-bottom-color: rgb(3=
4, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-ima=
ge-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; borde=
r-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34,=
 34); border-left-style: none; border-left-width: 0px; border-right-color: =
rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-=
top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; =
color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-le=
ft: 0px; padding-right: 0px; padding-top: 0px;"></u><sub style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; m=
argin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px;=
 padding-top: 0px;"></sub><sup style=3D"border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bo=
ttom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bo=
ttom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></sup>=
<strike style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;"></strike><br style=3D"border-=
bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-wid=
th: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image=
-slice: 100%; border-image-source: none; border-image-width: 1; border-left=
-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; b=
order-right-color: rgb(34, 34, 34); border-right-style: none; border-right-=
width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bord=
er-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><d=
iv style=3D"background-color: transparent; border-bottom-color: rgb(34, 34,=
 34); border-bottom-style: none; border-bottom-width: 0px; border-image-out=
set: 0; border-image-repeat: stretch; border-image-slice: 100%; border-imag=
e-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); =
border-left-style: none; border-left-width: 0px; border-right-color: rgb(34=
, 34, 34); border-right-style: none; border-right-width: 0px; border-top-co=
lor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color:=
 rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetic=
a&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><b styl=
e=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal;=
 margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; =
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0p=
x;"></b><i style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-sty=
le: none; border-bottom-width: 0px; border-image-outset: 0; border-image-re=
peat: stretch; border-image-slice: 100%; border-image-source: none; border-=
image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none=
; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right=
-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); b=
order-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-=
height: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ma=
rgin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; =
padding-top: 0px;"></i><u style=3D"border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddi=
ng-right: 0px; padding-top: 0px;"></u><sub style=3D"border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px;"></sub><sup style=3D"border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; pad=
ding-left: 0px; padding-right: 0px; padding-top: 0px;"></sup><strike style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"></strike><font face=3D"courier new,monospa=
ce" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: non=
e; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: s=
tretch; border-image-slice: 100%; border-image-source: none; border-image-w=
idth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; borde=
r-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style:=
 none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-t=
op-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px=
; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0p=
x; padding-right: 0px; padding-top: 0px;"></font><br style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
 padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
 text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D=
"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">auto cb1 =3D =
Fn&lt;void(const int&amp;)&gt;::from&lt;&amp;<span style=3D"background-colo=
r: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: =
inline; float: none; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; white-space: normal;=
 word-spacing: 0px;">func_cref</span>&gt;();<i style=3D"border-bottom-color=
: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bor=
der-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%=
; border-image-source: none; border-image-width: 1; border-left-color: rgb(=
34, 34, 34); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; =
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width=
: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; pad=
ding-left: 0px; padding-right: 0px; padding-top: 0px;"> //&lt; void Fn::ope=
rator(<span style=3D"background-color: transparent; border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); display: inline; float: none; font-family: couri=
er new,monospace; font-size: 13px; font-variant: normal; font-weight: 400; =
letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-ind=
ent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;">co=
nst int&amp; &amp;&amp;</span>) const --&gt; </i><span style=3D"background-=
color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-sty=
le: none; border-bottom-width: 0px; border-image-outset: 0; border-image-re=
peat: stretch; border-image-slice: 100%; border-image-source: none; border-=
image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none=
; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right=
-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); b=
order-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); displ=
ay: inline; float: none; font-family: courier new,monospace; font-size: 13p=
x; font-style: italic; font-variant: normal; font-weight: 400; letter-spaci=
ng: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin=
-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padd=
ing-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; te=
xt-transform: none; white-space: normal; word-spacing: 0px;">Fn::operator(<=
/span><span style=3D"background-color: transparent; border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); display: inline; float: none; font-family: couri=
er new,monospace; font-size: 13px; font-style: italic; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-lef=
t: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; white-space: normal; wo=
rd-spacing: 0px;">const int&amp;</span><span style=3D"background-color: tra=
nsparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; =
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stre=
tch; border-image-slice: 100%; border-image-source: none; border-image-widt=
h: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-l=
eft-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: no=
ne; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-=
style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline=
; float: none; font-family: courier new,monospace; font-size: 13px; font-st=
yle: italic; font-variant: normal; font-weight: 400; letter-spacing: normal=
; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;=
 padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0=
px; text-align: left; text-decoration: none; text-indent: 0px; text-transfo=
rm: none; white-space: normal; word-spacing: 0px;">)</span></font></div><di=
v style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, =
34); border-bottom-style: none; border-bottom-width: 0px; border-image-outs=
et: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image=
-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); b=
order-left-style: none; border-left-width: 0px; border-right-color: rgb(34,=
 34, 34); border-right-style: none; border-right-width: 0px; border-top-col=
or: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: =
rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica=
&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: n=
ormal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom:=
 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font fa=
ce=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><span st=
yle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); display: inline; float: none; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding=
-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text=
-align: left; text-decoration: none; text-indent: 0px; text-transform: none=
; white-space: normal; word-spacing: 0px;">auto cb2 =3D Fn&lt;void(int&amp;=
&amp;)&gt;::from&lt;&amp;</span><span style=3D"border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; ma=
rgin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; pad=
ding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"=
>func_<span style=3D"background-color: transparent; border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); display: inline; float: none; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top=
: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-=
top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; white-space: normal; word-spacing: 0px;">rr<wbr style=3D"bo=
rder-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-botto=
m-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-=
image-slice: 100%; border-image-source: none; border-image-width: 1; border=
-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-r=
ight-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none;=
 border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px;">ef</span></span><span style=3D"background-color:=
 transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: in=
line; float: none; font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-le=
ft: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; white-space: normal; w=
ord-spacing: 0px;">&gt;();<i style=3D"border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><span st=
yle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); display: inline; float: none; font-family: courier new,monospa=
ce; font-size: 13px; font-variant: normal; font-weight: 400; letter-spacing=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text=
-transform: none; white-space: normal; word-spacing: 0px;"> //&lt; void Fn:=
:operator(</span><span style=3D"background-color: transparent; border-botto=
m-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0=
px; border-image-outset: 0; border-image-repeat: stretch; border-image-slic=
e: 100%; border-image-source: none; border-image-width: 1; border-left-colo=
r: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border=
-right-color: rgb(34, 34, 34); border-right-style: none; border-right-width=
: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-to=
p-width: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-fa=
mily: courier new,monospace; font-size: 13px; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; ma=
rgin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; p=
adding-right: 0px; padding-top: 0px; text-align: left; text-decoration: non=
e; text-indent: 0px; text-transform: none; white-space: normal; word-spacin=
g: 0px;">int&amp;&amp; &amp;&amp;</span></i><span style=3D"background-color=
: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: n=
one; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat:=
 stretch; border-image-slice: 100%; border-image-source: none; border-image=
-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bor=
der-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-styl=
e: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border=
-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: i=
nline; float: none; font-family: courier new,monospace; font-size: 13px; fo=
nt-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; white=
-space: normal; word-spacing: 0px;"><i style=3D"border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; m=
argin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; pa=
dding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;=
">) const</i><i style=3D"border-bottom-color: rgb(34, 34, 34); border-botto=
m-style: none; border-bottom-width: 0px; border-image-outset: 0; border-ima=
ge-repeat: stretch; border-image-slice: 100%; border-image-source: none; bo=
rder-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style:=
 none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-=
right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 3=
4); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padd=
ing-left: 0px; padding-right: 0px; padding-top: 0px;"> --&gt; </i><span sty=
le=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); =
border-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0=
; border-image-repeat: stretch; border-image-slice: 100%; border-image-sour=
ce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border=
-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, =
34); border-right-style: none; border-right-width: 0px; border-top-color: r=
gb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(3=
4, 34, 34); display: inline; float: none; font-family: courier new,monospac=
e; font-size: 13px; font-style: italic; font-variant: normal; font-weight: =
400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-r=
ight: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding=
-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; tex=
t-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px=
;">Fn::operator(</span><span style=3D"background-color: transparent; border=
-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-wi=
dth: 0px; border-image-outset: 0; border-image-repeat: stretch; border-imag=
e-slice: 100%; border-image-source: none; border-image-width: 1; border-lef=
t-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; =
border-right-color: rgb(34, 34, 34); border-right-style: none; border-right=
-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; bor=
der-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: none; f=
ont-family: courier new,monospace; font-size: 13px; font-style: italic; fon=
t-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom:=
 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom:=
 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; white-=
space: normal; word-spacing: 0px;">int&amp;&amp;</span><span style=3D"backg=
round-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34);=
 display: inline; float: none; font-family: courier new,monospace; font-siz=
e: 13px; font-style: italic; font-variant: normal; font-weight: 400; letter=
-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px=
; padding-top: 0px; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; white-space: normal; word-spacing: 0px;">)</span>=
</span></span></font><b style=3D"border-bottom-color: rgb(34, 34, 34); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-lef=
t-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34);=
 border-right-style: none; border-right-width: 0px; border-top-color: rgb(3=
4, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 3=
4, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-r=
ight: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding=
-right: 0px; padding-top: 0px;"></b><i style=3D"border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-lef=
t: 0px; padding-right: 0px; padding-top: 0px;"></i><u style=3D"border-botto=
m-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0=
px; border-image-outset: 0; border-image-repeat: stretch; border-image-slic=
e: 100%; border-image-source: none; border-image-width: 1; border-left-colo=
r: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border=
-right-color: rgb(34, 34, 34); border-right-style: none; border-right-width=
: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-to=
p-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></u><sub styl=
e=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; borde=
r-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; =
border-image-slice: 100%; border-image-source: none; border-image-width: 1;=
 border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-w=
idth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; b=
order-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style=
: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin=
-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddi=
ng-right: 0px; padding-top: 0px;"></sub><sup style=3D"border-bottom-color: =
rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; borde=
r-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; =
border-image-source: none; border-image-width: 1; border-left-color: rgb(34=
, 34, 34); border-left-style: none; border-left-width: 0px; border-right-co=
lor: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bo=
rder-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: =
0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0=
px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top=
: 0px;"></sup><strike style=3D"border-bottom-color: rgb(34, 34, 34); border=
-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bord=
er-image-repeat: stretch; border-image-slice: 100%; border-image-source: no=
ne; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-=
style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); b=
order-right-style: none; border-right-width: 0px; border-top-color: rgb(34,=
 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0px=
; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></strike><br st=
yle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; color: rgb(34, 34, 34); line-height: norma=
l; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px;"></div><div style=3D"background-color: transparent; border-bottom-colo=
r: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(34, 34, 34); border-left-style: none; border-left-width: 0px; border-right=
-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px;=
 border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-widt=
h: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp=
;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; =
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0p=
x; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
 0px;"><b style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
 border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-h=
eight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></b><i style=3D"border-bottom-color: rgb(34, 34, 34); bor=
der-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; b=
order-image-repeat: stretch; border-image-slice: 100%; border-image-source:=
 none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-le=
ft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34)=
; border-right-style: none; border-right-width: 0px; border-top-color: rgb(=
34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, =
34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-=
right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px;"></i><u style=3D"border-bottom-color: rgb(3=
4, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-ima=
ge-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; borde=
r-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34,=
 34); border-left-style: none; border-left-width: 0px; border-right-color: =
rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-=
top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; =
color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-le=
ft: 0px; padding-right: 0px; padding-top: 0px;"></u><sub style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; m=
argin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px;=
 padding-top: 0px;"></sub><sup style=3D"border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bo=
ttom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bo=
ttom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></sup>=
<strike style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;"></strike><font face=3D"courie=
r new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; pad=
ding-left: 0px; padding-right: 0px; padding-top: 0px;"></font><b style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></=
b><i style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-height=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px;"></i><u style=3D"border-bottom-color: rgb(34, 34, 34); border-b=
ottom-style: none; border-bottom-width: 0px; border-image-outset: 0; border=
-image-repeat: stretch; border-image-slice: 100%; border-image-source: none=
; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-st=
yle: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bor=
der-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 3=
4, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 3=
4); line-height: normal; margin-bottom: 0px; margin-left: 0px; margin-right=
: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-rig=
ht: 0px; padding-top: 0px;"></u><sub style=3D"border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; mar=
gin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padd=
ing-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=
</sub><sup style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-sty=
le: none; border-bottom-width: 0px; border-image-outset: 0; border-image-re=
peat: stretch; border-image-slice: 100%; border-image-source: none; border-=
image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none=
; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right=
-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); b=
order-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-le=
ft: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-l=
eft: 0px; padding-right: 0px; padding-top: 0px;"></sup><strike style=3D"bor=
der-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom=
-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-i=
mage-slice: 100%; border-image-source: none; border-image-width: 1; border-=
left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0p=
x; border-right-color: rgb(34, 34, 34); border-right-style: none; border-ri=
ght-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; =
border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: =
0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right=
: 0px; padding-top: 0px;"></strike><i style=3D"border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;"></i><b style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></b><i style=
=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border=
-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; b=
order-image-slice: 100%; border-image-source: none; border-image-width: 1; =
border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wi=
dth: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bo=
rder-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style:=
 none; border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; =
margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
;"></i><u style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
 border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); line-h=
eight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></u><sub style=3D"border-bottom-color: rgb(34, 34, 34); b=
order-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0;=
 border-image-repeat: stretch; border-image-slice: 100%; border-image-sourc=
e: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-=
left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 3=
4); border-right-style: none; border-right-width: 0px; border-top-color: rg=
b(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></sub><sup=
 style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; =
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stre=
tch; border-image-slice: 100%; border-image-source: none; border-image-widt=
h: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-l=
eft-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: no=
ne; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-=
style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; m=
argin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; =
padding-right: 0px; padding-top: 0px;"></sup><strike style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margi=
n-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pad=
ding-top: 0px;"></strike><br style=3D"border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: 0px; mar=
gin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pa=
dding-right: 0px; padding-top: 0px;"></div><div style=3D"background-color: =
transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: non=
e; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: s=
tretch; border-image-slice: 100%; border-image-source: none; border-image-w=
idth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; borde=
r-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style:=
 none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-t=
op-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family:=
 &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">Effectively, we have &quot;manual&quo=
t; &quot;forwarding references&quot;.</div><div style=3D"background-color: =
transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: non=
e; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: s=
tretch; border-image-slice: 100%; border-image-source: none; border-image-w=
idth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; borde=
r-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style:=
 none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-t=
op-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family:=
 &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"backg=
round-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34);=
 font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-=
serif; font-size: 13px; font-style: normal; font-variant: normal; font-weig=
ht: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-le=
ft: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wi=
dth: 0px; white-space: normal; word-spacing: 0px;">Does the standard take t=
hese into account as such?=C2=A0</div><div style=3D"background-color: trans=
parent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bo=
rder-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretc=
h; border-image-slice: 100%; border-image-source: none; border-image-width:=
 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-lef=
t-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none=
; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-st=
yle: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp=
;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: =
13px; font-style: normal; font-variant: normal; font-weight: 400; letter-sp=
acing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-r=
ight: 0px; padding-top: 0px; text-align: left; text-decoration: none; text-=
indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-sp=
ace: normal; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;"></div><div style=3D"background=
-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-st=
yle: none; border-bottom-width: 0px; border-image-outset: 0; border-image-r=
epeat: stretch; border-image-slice: 100%; border-image-source: none; border=
-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: non=
e; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-righ=
t-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); =
border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font=
-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0=
px; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;"><br style=3D"border-bottom-co=
lor: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; =
border-image-outset: 0; border-image-repeat: stretch; border-image-slice: 1=
00%; border-image-source: none; border-image-width: 1; border-left-color: r=
gb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-rig=
ht-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0p=
x; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wi=
dth: 0px; color: rgb(34, 34, 34); line-height: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; =
padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br style=3D"bo=
rder-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-botto=
m-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-=
image-slice: 100%; border-image-source: none; border-image-width: 1; border=
-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-r=
ight-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none;=
 border-top-width: 0px; color: rgb(34, 34, 34); line-height: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding=
-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></d=
iv><div style=3D"background-color: transparent; border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Hel=
vetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">As=
 <span style=3D"background-color: transparent; border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); display: inline; float: none; font-family: &amp;quot;=
Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; =
font-style: normal; font-variant: normal; font-weight: 400; letter-spacing:=
 normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-to=
p: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding=
-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-=
transform: none; white-space: normal; word-spacing: 0px;">Florian pointed o=
ut - metaprogramming could lead to a &quot;forwarding reference&quot; &quot=
;in the end&quot;.=C2=A0</span><span style=3D"background-color: transparent=
; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-b=
ottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bor=
der-image-slice: 100%; border-image-source: none; border-image-width: 1; bo=
rder-left-color: rgb(34, 34, 34); border-left-style: none; border-left-widt=
h: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bord=
er-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: n=
one; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; float:=
 none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;=
,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; fon=
t-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px=
; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0p=
x; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration:=
 none; text-indent: 0px; text-transform: none; white-space: normal; word-sp=
acing: 0px;"><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; pad=
ding-left: 0px; padding-right: 0px; padding-top: 0px;"></span></div><div st=
yle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); borde=
r-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34,=
 34); border-right-style: none; border-right-width: 0px; border-top-color: =
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(=
34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp=
;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norma=
l; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); display: inline; float: none; font-family: &amp;quot;Arial&amp;qu=
ot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: =
normal; font-variant: normal; font-weight: 400; letter-spacing: normal; mar=
gin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padd=
ing-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; t=
ext-align: left; text-decoration: none; text-indent: 0px; text-transform: n=
one; white-space: normal; word-spacing: 0px;"><br style=3D"border-bottom-co=
lor: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; =
border-image-outset: 0; border-image-repeat: stretch; border-image-slice: 1=
00%; border-image-source: none; border-image-width: 1; border-left-color: r=
gb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-rig=
ht-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0p=
x; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wi=
dth: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px;"></span></div><div style=3D"background-color: transparent; bord=
er-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-=
width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-im=
age-slice: 100%; border-image-source: none; border-image-width: 1; border-l=
eft-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px=
; border-right-color: rgb(34, 34, 34); border-right-style: none; border-rig=
ht-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; b=
order-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&=
amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-s=
tyle: normal; font-variant: normal; font-weight: 400; letter-spacing: norma=
l; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px;=
 text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal;=
 word-spacing: 0px;"><span style=3D"background-color: transparent; border-b=
ottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-widt=
h: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-=
slice: 100%; border-image-source: none; border-image-width: 1; border-left-=
color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bo=
rder-right-color: rgb(34, 34, 34); border-right-style: none; border-right-w=
idth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; borde=
r-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: none; fon=
t-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-seri=
f; font-size: 13px; font-style: normal; font-variant: normal; font-weight: =
400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-r=
ight: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding=
-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; tex=
t-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px=
;"><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;"></span></div><div style=3D"bac=
kground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-sty=
le: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bord=
er-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34=
, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34=
); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; ma=
rgin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-=
left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"backgro=
und-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom=
-style: none; border-bottom-width: 0px; border-image-outset: 0; border-imag=
e-repeat: stretch; border-image-slice: 100%; border-image-source: none; bor=
der-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: =
none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-r=
ight-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34=
); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); d=
isplay: inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;qu=
ot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; fon=
t-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom:=
 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom:=
 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; white-=
space: normal; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; m=
argin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; pa=
dding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;=
"></span></div><div style=3D"background-color: transparent; border-bottom-c=
olor: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px;=
 border-image-outset: 0; border-image-repeat: stretch; border-image-slice: =
100%; border-image-source: none; border-image-width: 1; border-left-color: =
rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-ri=
ght-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0=
px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-w=
idth: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&=
amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: norma=
l; font-variant: normal; font-weight: 400; letter-spacing: normal; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: =
2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top:=
 0px; text-align: left; text-decoration: none; text-indent: 0px; text-trans=
form: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spaci=
ng: 0px;"><span style=3D"background-color: transparent; border-bottom-color=
: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bor=
der-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%=
; border-image-source: none; border-image-width: 1; border-left-color: rgb(=
34, 34, 34); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; =
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width=
: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-family: &=
amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-siz=
e: 13px; font-style: normal; font-variant: normal; font-weight: 400; letter=
-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px=
; padding-top: 0px; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; white-space: normal; word-spacing: 0px;">I think =
that is an important question, not just for this proposal, but in general, =
as teachability stand point for instance.=C2=A0</span></div><div style=3D"b=
ackground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-=
bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; borde=
r-image-repeat: stretch; border-image-slice: 100%; border-image-source: non=
e; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-s=
tyle: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); bo=
rder-right-style: none; border-right-width: 0px; border-top-color: rgb(34, =
34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, =
34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; =
margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-d=
ecoration: none; text-indent: 0px; text-transform: none; -webkit-text-strok=
e-width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"backg=
round-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34);=
 display: inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;=
quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; f=
ont-variant: normal; font-weight: 400; letter-spacing: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; whit=
e-space: normal; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb(=
34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-im=
age-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bord=
er-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34=
, 34); border-left-style: none; border-left-width: 0px; border-right-color:=
 rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border=
-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px;=
 margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; =
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0p=
x;"></span></div><div style=3D"background-color: transparent; border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;=
,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans=
: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-family:=
 &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0=
px; padding-top: 0px; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; white-space: normal; word-spacing: 0px;">If we =
say <b style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;">NO</b>, how can we explain the=
 correct and advised use of forward to a beginner/intermediate?</span></div=
><div style=3D"background-color: transparent; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helve=
tica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-varian=
t: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; ma=
rgin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bot=
tom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-ali=
gn: left; text-decoration: none; text-indent: 0px; text-transform: none; -w=
ebkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><spa=
n style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, =
34); border-bottom-style: none; border-bottom-width: 0px; border-image-outs=
et: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image=
-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); b=
order-left-style: none; border-left-width: 0px; border-right-color: rgb(34,=
 34, 34); border-right-style: none; border-right-width: 0px; border-top-col=
or: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: =
rgb(34, 34, 34); display: inline; float: none; font-family: &amp;quot;Arial=
&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-=
style: normal; font-variant: normal; font-weight: 400; letter-spacing: norm=
al; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0p=
x; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top:=
 0px; text-align: left; text-decoration: none; text-indent: 0px; text-trans=
form: none; white-space: normal; word-spacing: 0px;"><br style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; m=
argin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px;=
 padding-top: 0px;"></span></div><div style=3D"background-color: transparen=
t; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-=
bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bo=
rder-image-slice: 100%; border-image-source: none; border-image-width: 1; b=
order-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wid=
th: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bor=
der-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: =
none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot=
;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;"><span style=3D"background-color: transparent; b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: no=
ne; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; m=
argin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; =
padding-right: 0px; padding-top: 0px; text-align: left; text-decoration: no=
ne; text-indent: 0px; text-transform: none; white-space: normal; word-spaci=
ng: 0px;">If we say <b style=3D"border-bottom-color: rgb(34, 34, 34); borde=
r-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bor=
der-image-repeat: stretch; border-image-slice: 100%; border-image-source: n=
one; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left=
-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); =
border-right-style: none; border-right-width: 0px; border-top-color: rgb(34=
, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px;">YES</b>, then =
isn&#39;t the example in the standard somewhat incorrect by claiming T&amp;=
&amp; is NOT a frw ref.=C2=A0</span><span style=3D"background-color: transp=
arent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; f=
loat: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-lef=
t: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; white-space: normal; wo=
rd-spacing: 0px;"><br style=3D"border-bottom-color: rgb(34, 34, 34); border=
-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bord=
er-image-repeat: stretch; border-image-slice: 100%; border-image-source: no=
ne; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-=
style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); b=
order-right-style: none; border-right-width: 0px; border-top-color: rgb(34,=
 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0px=
; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px=
; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></span></div><d=
iv style=3D"background-color: transparent; border-bottom-color: rgb(34, 34,=
 34); border-bottom-style: none; border-bottom-width: 0px; border-image-out=
set: 0; border-image-repeat: stretch; border-image-slice: 100%; border-imag=
e-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); =
border-left-style: none; border-left-width: 0px; border-right-color: rgb(34=
, 34, 34); border-right-style: none; border-right-width: 0px; border-top-co=
lor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color:=
 rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetic=
a&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span s=
tyle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34)=
; border-bottom-style: none; border-bottom-width: 0px; border-image-outset:=
 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-so=
urce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bord=
er-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34=
, 34); border-right-style: none; border-right-width: 0px; border-top-color:=
 rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb=
(34, 34, 34); display: inline; float: none; font-size: 13px; font-style: no=
rmal; font-variant: normal; font-weight: 400; letter-spacing: normal; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; tex=
t-align: left; text-decoration: none; text-indent: 0px; text-transform: non=
e; white-space: normal; word-spacing: 0px;"><font face=3D"courier new,monos=
pace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: n=
one; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat:=
 stretch; border-image-slice: 100%; border-image-source: none; border-image=
-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bor=
der-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-styl=
e: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border=
-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0=
px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: =
0px; padding-right: 0px; padding-top: 0px;"></font><br style=3D"border-bott=
om-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: =
0px; border-image-outset: 0; border-image-repeat: stretch; border-image-sli=
ce: 100%; border-image-source: none; border-image-width: 1; border-left-col=
or: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; borde=
r-right-color: rgb(34, 34, 34); border-right-style: none; border-right-widt=
h: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-t=
op-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></span></div><div style=3D"background-color: transparent;=
 border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bo=
ttom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bord=
er-image-slice: 100%; border-image-source: none; border-image-width: 1; bor=
der-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width=
: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; borde=
r-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: no=
ne; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;A=
rial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top=
: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0=
px; padding-top: 0px; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;"><span style=3D"background-color: transparent; bor=
der-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom=
-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-i=
mage-slice: 100%; border-image-source: none; border-image-width: 1; border-=
left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0p=
x; border-right-color: rgb(34, 34, 34); border-right-style: none; border-ri=
ght-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; =
border-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: none=
; font-size: 13px; font-variant: normal; letter-spacing: normal; margin-bot=
tom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bot=
tom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-ali=
gn: left; text-indent: 0px; text-transform: none; white-space: normal; word=
-spacing: 0px;"><font face=3D"courier new,monospace" style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margi=
n-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pad=
ding-top: 0px;"><span style=3D"background-color: transparent; border-bottom=
-color: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; =
border-image-outset: 0; border-image-repeat: stretch; border-image-slice: 1=
00%; border-image-source: none; border-image-width: 1; border-left-color: r=
gb(0, 0, 0); border-left-style: none; border-left-width: 0px; border-right-=
color: rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; bor=
der-top-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px;=
 color: rgb(0, 0, 0); display: inline; float: none; font-size: 13.33px; fon=
t-style: normal; font-variant: normal; font-weight: 400; letter-spacing: no=
rmal; line-height: 17.33px; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-=
right: 0px; padding-top: 0px; text-align: justify; text-decoration: none; t=
ext-indent: 0px; text-transform: none; white-space: pre; word-spacing: 0px;=
">template &lt;class T&gt; struct A {<br style=3D"border-bottom-color: rgb(=
0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(0, 0, 0);=
 border-left-style: none; border-left-width: 0px; border-right-color: rgb(0=
, 0, 0); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0 t=
emplate &lt;class U&gt;<br style=3D"border-bottom-color: rgb(0, 0, 0); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(0, 0, 0); border-left-s=
tyle: none; border-left-width: 0px; border-right-color: rgb(0, 0, 0); borde=
r-right-style: none; border-right-width: 0px; border-top-color: rgb(0, 0, 0=
); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;">=C2=A0=C2=A0=C2=A0 A(T=
&amp;&amp;, U&amp;&amp;, int*);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 </span><span style=3D"background-color: transparent; border-bo=
ttom-color: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0=
px; border-image-outset: 0; border-image-repeat: stretch; border-image-slic=
e: 100%; border-image-source: none; border-image-width: 1; border-left-colo=
r: rgb(0, 0, 0); border-left-style: none; border-left-width: 0px; border-ri=
ght-color: rgb(0, 0, 0); border-right-style: none; border-right-width: 0px;=
 border-top-color: rgb(0, 0, 0); border-top-style: none; border-top-width: =
0px; color: rgb(0, 0, 0); font-size: 13.33px; font-style: italic; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; =
padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justif=
y; text-decoration: none; text-indent: 0px; text-transform: none; white-spa=
ce: pre; word-spacing: 0px;">// #1: <span style=3D"border-bottom-color: rgb=
(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(0, 0, 0)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
0, 0, 0); border-right-style: none; border-right-width: 0px; border-top-col=
or: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; font-style=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; paddin=
g-top: 0px;">T&amp;&amp;</span> is not a forwarding reference.<br style=3D"=
border-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-bottom=
-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-i=
mage-slice: 100%; border-image-source: none; border-image-width: 1; border-=
left-color: rgb(0, 0, 0); border-left-style: none; border-left-width: 0px; =
border-right-color: rgb(0, 0, 0); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(0, 0, 0); border-top-style: none; border-to=
p-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; marg=
in-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pa=
dding-top: 0px;"></span><span style=3D"background-color: transparent; borde=
r-bottom-color: rgb(0, 0, 0); border-bottom-style: none; border-bottom-widt=
h: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-=
slice: 100%; border-image-source: none; border-image-width: 1; border-left-=
color: rgb(0, 0, 0); border-left-style: none; border-left-width: 0px; borde=
r-right-color: rgb(0, 0, 0); border-right-style: none; border-right-width: =
0px; border-top-color: rgb(0, 0, 0); border-top-style: none; border-top-wid=
th: 0px; color: rgb(0, 0, 0); display: inline; float: none; font-size: 13.3=
3px; font-style: normal; font-variant: normal; font-weight: 400; letter-spa=
cing: normal; line-height: 17.33px; margin-bottom: 0px; margin-left: 0px; m=
argin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; =
padding-right: 0px; padding-top: 0px; text-align: justify; text-decoration:=
 none; text-indent: 0px; text-transform: none; white-space: pre; word-spaci=
ng: 0px;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<wbr style=3D"border-bottom-color=
: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; border=
-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; b=
order-image-source: none; border-image-width: 1; border-left-color: rgb(0, =
0, 0); border-left-style: none; border-left-width: 0px; border-right-color:=
 rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=
=C2=A0 </span><span style=3D"background-color: transparent; border-bottom-c=
olor: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(0, 0, 0); border-left-style: none; border-left-width: 0px; border-right-co=
lor: rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; c=
olor: rgb(0, 0, 0); font-size: 13.33px; font-style: italic; font-variant: n=
ormal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify; tex=
t-decoration: none; text-indent: 0px; text-transform: none; white-space: pr=
e; word-spacing: 0px;">// <span style=3D"border-bottom-color: rgb(0, 0, 0);=
 border-bottom-style: none; border-bottom-width: 0px; border-image-outset: =
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-sou=
rce: none; border-image-width: 1; border-left-color: rgb(0, 0, 0); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(0, 0, 0); =
border-right-style: none; border-right-width: 0px; border-top-color: rgb(0,=
 0, 0); border-top-style: none; border-top-width: 0px; font-style: normal; =
margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
;">U&amp;&amp;</span> is a forwarding reference.<br style=3D"border-bottom-=
color: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(0, 0, 0); border-left-style: none; border-left-width: 0px; border-right-c=
olor: rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; =
margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
;"></span><span style=3D"background-color: transparent; border-bottom-color=
: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; border=
-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; b=
order-image-source: none; border-image-width: 1; border-left-color: rgb(0, =
0, 0); border-left-style: none; border-left-width: 0px; border-right-color:=
 rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; color=
: rgb(0, 0, 0); display: inline; float: none; font-size: 13.33px; font-styl=
e: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; =
line-height: 17.33px; margin-bottom: 0px; margin-left: 0px; margin-right: 0=
px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px; text-align: justify; text-decoration: none; text-in=
dent: 0px; text-transform: none; white-space: pre; word-spacing: 0px;">=C2=
=A0 ...</span><span style=3D"background-color: transparent; border-bottom-c=
olor: rgb(0, 0, 0); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(0, 0, 0); border-left-style: none; border-left-width: 0px; border-right-co=
lor: rgb(0, 0, 0); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(0, 0, 0); border-top-style: none; border-top-width: 0px; c=
olor: rgb(0, 0, 0); font-size: 13.33px; font-style: italic; font-variant: n=
ormal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify; tex=
t-decoration: none; text-indent: 0px; text-transform: none; white-space: pr=
e; word-spacing: 0px;"><br style=3D"border-bottom-color: rgb(0, 0, 0); bord=
er-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bo=
rder-image-repeat: stretch; border-image-slice: 100%; border-image-source: =
none; border-image-width: 1; border-left-color: rgb(0, 0, 0); border-left-s=
tyle: none; border-left-width: 0px; border-right-color: rgb(0, 0, 0); borde=
r-right-style: none; border-right-width: 0px; border-top-color: rgb(0, 0, 0=
); border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margi=
n-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px;"></span><span style=3D"=
background-color: transparent; border-bottom-color: rgb(0, 0, 0); border-bo=
ttom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-=
image-repeat: stretch; border-image-slice: 100%; border-image-source: none;=
 border-image-width: 1; border-left-color: rgb(0, 0, 0); border-left-style:=
 none; border-left-width: 0px; border-right-color: rgb(0, 0, 0); border-rig=
ht-style: none; border-right-width: 0px; border-top-color: rgb(0, 0, 0); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(0, 0, 0); display: =
inline; float: none; font-size: 13.33px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; line-height: 17.33px; mar=
gin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padd=
ing-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; t=
ext-align: justify; text-decoration: none; text-indent: 0px; text-transform=
: none; white-space: pre; word-spacing: 0px;">};</span></font><b style=3D"b=
order-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bott=
om-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border=
-image-slice: 100%; border-image-source: none; border-image-width: 1; borde=
r-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: =
0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-=
right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none=
; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right=
: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-rig=
ht: 0px; padding-top: 0px;"></b><i style=3D"border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
 border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margi=
n-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></=
i><u style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0p=
x; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0=
px; padding-right: 0px; padding-top: 0px;"></u><sub style=3D"border-bottom-=
color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px=
; border-image-outset: 0; border-image-repeat: stretch; border-image-slice:=
 100%; border-image-source: none; border-image-width: 1; border-left-color:=
 rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-r=
ight-color: rgb(34, 34, 34); border-right-style: none; border-right-width: =
0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-=
width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin=
-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padd=
ing-top: 0px;"></sub><sup style=3D"border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom:=
 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom:=
 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></sup><stri=
ke style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none=
; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: st=
retch; border-image-slice: 100%; border-image-source: none; border-image-wi=
dth: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border=
-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: =
none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-to=
p-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px;=
 margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px=
; padding-right: 0px; padding-top: 0px;"></strike><br style=3D"border-botto=
m-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0=
px; border-image-outset: 0; border-image-repeat: stretch; border-image-slic=
e: 100%; border-image-source: none; border-image-width: 1; border-left-colo=
r: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border=
-right-color: rgb(34, 34, 34); border-right-style: none; border-right-width=
: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-to=
p-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; marg=
in-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pa=
dding-top: 0px;"></span></div><div style=3D"background-color: transparent; =
border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bot=
tom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; borde=
r-image-slice: 100%; border-image-source: none; border-image-width: 1; bord=
er-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width:=
 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border=
-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: non=
e; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Ar=
ial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; fo=
nt-style: normal; font-variant: normal; font-weight: 400; letter-spacing: n=
ormal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top:=
 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0p=
x; padding-top: 0px; text-align: left; text-decoration: none; text-indent: =
0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: nor=
mal; word-spacing: 0px;"><span style=3D"background-color: transparent; bord=
er-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-=
width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-im=
age-slice: 100%; border-image-source: none; border-image-width: 1; border-l=
eft-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px=
; border-right-color: rgb(34, 34, 34); border-right-style: none; border-rig=
ht-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; b=
order-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: none;=
 font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-=
serif; font-size: 13px; font-style: normal; font-variant: normal; font-weig=
ht: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pad=
ding-right: 0px; padding-top: 0px; text-align: left; text-decoration: none;=
 text-indent: 0px; text-transform: none; white-space: normal; word-spacing:=
 0px;"><b style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
 border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-lef=
t: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-le=
ft: 0px; padding-right: 0px; padding-top: 0px;"></b><i style=3D"border-bott=
om-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: =
0px; border-image-outset: 0; border-image-repeat: stretch; border-image-sli=
ce: 100%; border-image-source: none; border-image-width: 1; border-left-col=
or: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; borde=
r-right-color: rgb(34, 34, 34); border-right-style: none; border-right-widt=
h: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-t=
op-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; mar=
gin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; p=
adding-top: 0px;"></i><u style=3D"border-bottom-color: rgb(34, 34, 34); bor=
der-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; b=
order-image-repeat: stretch; border-image-slice: 100%; border-image-source:=
 none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-le=
ft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34)=
; border-right-style: none; border-right-width: 0px; border-top-color: rgb(=
34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: =
0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: =
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></u><sub sty=
le=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bord=
er-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch;=
 border-image-slice: 100%; border-image-source: none; border-image-width: 1=
; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-=
width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; =
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-styl=
e: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margi=
n-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px;"></sub><sup style=3D"border-bottom-color:=
 rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bord=
er-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%;=
 border-image-source: none; border-image-width: 1; border-left-color: rgb(3=
4, 34, 34); border-left-style: none; border-left-width: 0px; border-right-c=
olor: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; b=
order-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width:=
 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: =
0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px;"></sup><strike style=3D"border-bottom-color: rgb(34, 34, 34); borde=
r-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bor=
der-image-repeat: stretch; border-image-slice: 100%; border-image-source: n=
one; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left=
-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); =
border-right-style: none; border-right-width: 0px; border-top-color: rgb(34=
, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></strike><font=
 face=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-b=
ottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></fon=
t><br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: n=
one; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat:=
 stretch; border-image-slice: 100%; border-image-source: none; border-image=
-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bor=
der-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-styl=
e: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border=
-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0=
px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: =
0px; padding-right: 0px; padding-top: 0px;"></span></div><div style=3D"back=
ground-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bot=
tom-style: none; border-bottom-width: 0px; border-image-outset: 0; border-i=
mage-repeat: stretch; border-image-slice: 100%; border-image-source: none; =
border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-styl=
e: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); borde=
r-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34,=
 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34)=
; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; mar=
gin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-l=
eft: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"backgrou=
nd-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-=
style: none; border-bottom-width: 0px; border-image-outset: 0; border-image=
-repeat: stretch; border-image-slice: 100%; border-image-source: none; bord=
er-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: n=
one; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-ri=
ght-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34)=
; border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); di=
splay: inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quo=
t;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font=
-variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: =
0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: =
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: l=
eft; text-decoration: none; text-indent: 0px; text-transform: none; white-s=
pace: normal; word-spacing: 0px;">Shouldn&#39;t the correct answer &quot;it=
 depends&quot; (on the usage and instantiations of the class)?=C2=A0</span>=
</div><div style=3D"background-color: transparent; border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;=
Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; tex=
t-align: left; text-decoration: none; text-indent: 0px; text-transform: non=
e; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"=
><span style=3D"background-color: transparent; border-bottom-color: rgb(34,=
 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); display: inline; float: none; font-family: &amp;quot;=
Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; =
font-style: normal; font-variant: normal; font-weight: 400; letter-spacing:=
 normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-to=
p: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding=
-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-=
transform: none; white-space: normal; word-spacing: 0px;"><br></span></div>=
<div style=3D"background-color: transparent; border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvet=
ica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bott=
om: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span=
 style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 3=
4); border-bottom-style: none; border-bottom-width: 0px; border-image-outse=
t: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-=
source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bo=
rder-left-style: none; border-left-width: 0px; border-right-color: rgb(34, =
34, 34); border-right-style: none; border-right-width: 0px; border-top-colo=
r: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: r=
gb(34, 34, 34); display: inline; float: none; font-family: &amp;quot;Arial&=
amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-s=
tyle: normal; font-variant: normal; font-weight: 400; letter-spacing: norma=
l; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px=
; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: =
0px; text-align: left; text-decoration: none; text-indent: 0px; text-transf=
orm: none; white-space: normal; word-spacing: 0px;"><br></span></div><b></b=
><i></i><u></u><sub></sub><sup></sup><strike></strike><br></div><div>P.S</d=
iv><div><br></div><div>Currently the cppreference.com explicitly talks abou=
t argument deduction=C2=A0</div><div><i>Reference collapsing</i></div><div>=
<i>...</i></div><i>(This, along with special rules for template argument de=
duction when T&amp;&amp; is used in a function template, forms the rules th=
at make std::forward possible.) </i><div><b></b><i></i><u></u><sub></sub><s=
up></sup><strike></strike><i></i><br></div><div>=C2=A0</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"auto"><div dir=3D"auto"></div><di=
v dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex">=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.=
org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" target=
=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"e9O7oR40BQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"e9O7oR40BQAJ">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800=
-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad2=
77-7800-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" href=3D"https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-=
35cc-16d11e1c65d9%40gmail.com" target=3D"_blank" rel=3D"nofollow">https://g=
roups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/095ad277-7800=
-53e2-<wbr>35cc-16d11e1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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/284f098b-471e-4122-a26a-f58e0d8871d9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/284f098b-471e-4122-a26a-f58e0d8871d9=
%40isocpp.org</a>.<br />

------=_Part_72836_217948924.1528535664453--

------=_Part_72835_452938654.1528535664450--

.


Author: mihailnajdenov@gmail.com
Date: Sat, 9 Jun 2018 02:17:51 -0700 (PDT)
Raw View
------=_Part_72983_568539658.1528535871493
Content-Type: multipart/alternative;
 boundary="----=_Part_72984_1779315994.1528535871494"

------=_Part_72984_1779315994.1528535871494
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>
> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com
> <javascript:>> wrote:
>
>> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
>> >
>> > If one writes a function where he moves instead of forwarding
>> >
>> >
>> >     template< typename T >
>> >     void foo(T&& value)
>> >     {
>> >       vec.push_back(std::move(value));
>> >     }
>> > **//___^
>> > That will be *The Wrong Thing* to do.
>>
>> There's nothing wrong with it, as long as you actually want to move.
>>
>> > This is because one /lies against the interface /- T&& is a forwarding
>> > reference,/by definition/.
>> >
>> > Using "object passing", /prevents/ you to lie!
>>
>> There's no such thing as a forwarding reference in the language.
>
>
> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>


Interesting.
*Question*. Given T&& being a forwarding reference, if the type T is NOT
deduced but supplied by the user AND a reference collapsing still takes
place - can this still be considered "forwarding reference"

I imagine the answer is NO.

*However*. A real world example:

template<class fun>
class Fn;
template<class R, class... A>
class Fn<R(A...)>
{
  using F = R (*)(void*, A...);
  template<R (*f)(A...)>
  static R stub(void*, A&&... arg)
  {
    return (*f)(std::forward<A>(arg)...);
  }

  // ... other stubs to call member functions (_p is used then)

public:
  // ...
  template<R (*f)(A...)>
  static Fn from() noexcept
  {
    return {nullptr, &stub<f>};
  }

  // NOT forward reference, however...yeah
  R operator ()(A&&... args) const
  {
    return _f(_p, std::forward<A>(args)...);
  }

  void* _p;
  F _f;
};

In this example the operator() arguments will (need to) be "forwarding
references", though the type will not be deduced, but supplied by the user:

void func_cref(const int&) {}
void func_rref(int&&) {}
auto cb1 = Fn<void(const int&)>::from<&func_cref>(); *//< void
Fn::operator(const int& &&) const --> Fn::operator(const int&)*
auto cb2 = Fn<void(int&&)>::from<&func_rref>(); *//< void
Fn::operator(int&& &&) const --> Fn::operator(const int&)*

Effectively, we have "manual" "forwarding references".

Does the standard take these into account as such?

As Florian pointed out - metaprogramming could lead to a "forwarding
reference" "in the end".

I think that is an important question, not just for this proposal, but in
general, as teachability stand point for instance.

If we say *NO*, how can we explain the use of forward to a
beginner/intermediate?

If we say *YES*, then isn't the example in the standard somewhat incorrect
by claiming T&& is NOT a frw ref.

template <class T> struct A {
  template <class U>
    A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
                                // U&& is a forwarding reference.
  ...
};

Shouldn't the correct answer "it depends" (on the usage and instantiations
of the class)?


>
>  Using
>> T&&, where T is a template argument, for forwarding is just one use
>> case, but there are also other. For example, this syntax can be used for
>> generalization so that you don't have to write multiple overloads for
>> different argument types.
>>
>> > See a similar post from the original discussion for detailed explanation
>> >
>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>
>> Using SFINAE to force users to explicitly move is a good approach, but I
>> don't think it is always necessary. If my foo function is called, say,
>> foo_move and is properly documented, there's no reason to force users to
>> explicitly call std::move on their end. Especially, if the user is me,
>> the implementer of foo_move.
>>
>> >     Forwarding and moving a value have a fundamental difference in
>> >     strength.
>> >     Forwarding does not move the value unless permitted by the program
>> >     (i.e.
>> >     the value is assumed to be unused afterwards) while std::move is
>> >     stronger and will move even lvalue. The fact that both may end up
>> >     moving
>> >     the value does not mean they are the same and should be expressed
>> the
>> >     same way. Being more explicit about the intent is beneficial to the
>> >     developer, experienced or junior.
>> >
>> > Question is what is the original intend? And actually the intend in
>> both
>> > cases is to give the object away.
>>
>> That's from the function caller's perspective. And as far as the caller
>> is concerned, if you want to move, you use std::move. You never use
>> std::forward to move a value.
>>
>> As a function implementer (or, more accurately, receiver of the function
>> arguments), you can have different intentions wrt. the arguments. Some
>> of the arguments you may move, others forward, thirds modify or copy. My
>> point is that the compiler is not able and should not be given liberty
>> to decide which behavior to apply in each case. And the end code will
>> have better quality if this intent is apparent.
>>
>> > About the "ugliness".
>> >
>> > Well, I really hoped a simple && would do the trick, but it does clash
>> > with the binary operator && and I see no way around that.
>> >
>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>> > passin.
>>
>> These don't look any better to me, sorry. Ignoring for a moment that I
>> don't like the idea to begin with, I would prefer a function-style
>> keyword instead of new obscure operators, especially 3 or more
>> characters long.
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>> .
>>
>

--
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/0a1b2f51-a107-4c8b-9963-08ed1b2d73d1%40isocpp.org.

------=_Part_72984_1779315994.1528535871494
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richa=
rd Smith 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"aut=
o"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:=
33 Andrey Semashev, &lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" h=
ref=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailt=
o=3D"e9O7oR40BQAJ">andrey....@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On 06/08/18 09:32, <a onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-o=
bfuscated-mailto=3D"e9O7oR40BQAJ">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%=
2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" onclick=3D"th=
is.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%2Fc%2B%2B=
draft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" href=3D"http://eel.is/=
c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=3D"nofollow">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><br></div><div>Interesting. </div><div><=
b>Question</b>. Given T&amp;&amp; being a forwarding reference, if the type=
 T is NOT deduced but supplied by the user AND a reference collapsing still=
 takes place - can this still be considered &quot;forwarding reference&quot=
;</div><div><br></div><div>I imagine the answer is NO.</div><div><br><b>How=
ever</b>. A real world example:=C2=A0</div><div><font face=3D"courier new,m=
onospace"></font><br></div><div><font face=3D"courier new,monospace">templa=
te&lt;class fun&gt;<br>class Fn;</font></div><div><font face=3D"courier new=
,monospace">template&lt;class R, class... A&gt;<br>class Fn&lt;R(A...)&gt;<=
br>{<br>=C2=A0 using F =3D R (*)(void*, A...);</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 st=
atic R stub(void*, A&amp;&amp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 re=
turn (*f)(std::forward&lt;A&gt;(arg)...);<br>=C2=A0 }</font></div><div><fon=
t face=3D"courier new,monospace"><br></font></div><div><font face=3D"courie=
r new,monospace">=C2=A0 // ... other stubs to call member functions (_p is =
used then)</font></div><div><font face=3D"courier new,monospace"><br></font=
></div><div><font face=3D"courier new,monospace">public:<br>=C2=A0 // ...<b=
r>=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static Fn from() noexcept<b=
r>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;stub&lt;f&gt;};<br>=
=C2=A0 }<br>=C2=A0 <br>=C2=A0 // NOT forward reference, however...yeah</fon=
t></div><div><font face=3D"courier new,monospace">=C2=A0 R operator ()(A&am=
p;&amp;... args) const<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return _f(_p, std:=
:forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></div><div><font face=3D"cou=
rier new,monospace"><br>=C2=A0 void* _p;<br>=C2=A0 F _f;<br>};</font></div>=
<div><font face=3D"courier new,monospace"><br></font></div><div>In this exa=
mple the operator() arguments will (need to) be &quot;forwarding references=
&quot;, though the type will not be deduced, but supplied by the user:</div=
><div><br></div><div><font face=3D"courier new,monospace">void func_cref(co=
nst int&amp;) {}<br>void func_rref(int&amp;&amp;) {}</font></div><div><font=
 face=3D"courier new,monospace">auto cb1 =3D Fn&lt;void(const int&amp;)&gt;=
::from&lt;&amp;func_cref&gt;(); <i>//&lt; void Fn::operator(const int&amp; =
&amp;&amp;) const --&gt; Fn::operator(const int&amp;)</i><br>auto cb2 =3D F=
n&lt;void(int&amp;&amp;)&gt;::from&lt;&amp;func_rref&gt;(); <i>//&lt; void =
Fn::operator(int&amp;&amp; &amp;&amp;) const --&gt; Fn::operator(const int&=
amp;)</i></font></div><div><font face=3D"courier new,monospace"><i><br></i>=
</font></div><div>Effectively, we have &quot;manual&quot; &quot;forwarding =
references&quot;.</div><div><br></div><div>Does the standard take these int=
o account as such? </div><div><br></div><div>As Florian pointed out - metap=
rogramming could lead to a &quot;forwarding reference&quot; &quot;in the en=
d&quot;. </div><div><br></div><div>I think that is an important question, n=
ot just for this proposal, but in general, as teachability stand point for =
instance.=C2=A0</div><div><br></div><div>If we say <b>NO</b>, how can we ex=
plain the use of forward to a beginner/intermediate?</div><div><br></div><d=
iv>If we say <b>YES</b>, then isn&#39;t the example in the standard somewha=
t incorrect by claiming T&amp;&amp; is NOT a frw ref. </div><div><br><font =
face=3D"courier new,monospace">template &lt;class T&gt; struct A {<br>=C2=
=A0 template &lt;class U&gt;<br>=C2=A0=C2=A0=C2=A0 A(T&amp;&amp;, U&amp;&am=
p;, int*);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // #1: T&a=
mp;&amp; is not a forwarding reference.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 // U&amp;&amp; is a forwarding reference.<br>=C2=A0 ...<br>};</font>=
</div><div><font face=3D"courier new,monospace"><br></font></div><div>Shoul=
dn&#39;t the correct answer &quot;it depends&quot; (on the usage and instan=
tiations of the class)? <br></div><div>=C2=A0</div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div dir=3D"auto"><div dir=3D"auto"></div><div dir=3D"=
auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.=
org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" target=
=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"e9O7oR40BQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"e9O7oR40BQAJ">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800=
-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad2=
77-7800-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" href=3D"https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-=
35cc-16d11e1c65d9%40gmail.com" target=3D"_blank" rel=3D"nofollow">https://g=
roups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/095ad277-7800=
-53e2-<wbr>35cc-16d11e1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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/0a1b2f51-a107-4c8b-9963-08ed1b2d73d1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0a1b2f51-a107-4c8b-9963-08ed1b2d73d1=
%40isocpp.org</a>.<br />

------=_Part_72984_1779315994.1528535871494--

------=_Part_72983_568539658.1528535871493--

.


Author: mihailnajdenov@gmail.com
Date: Sat, 9 Jun 2018 02:21:12 -0700 (PDT)
Raw View
------=_Part_71927_1908177157.1528536072874
Content-Type: multipart/alternative;
 boundary="----=_Part_71928_1495364448.1528536072875"

------=_Part_71928_1495364448.1528536072875
Content-Type: text/plain; charset="UTF-8"



On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>
> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com
> <javascript:>> wrote:
>
>> On 06/08/18 09:32, mihailn...@gmail.com <javascript:> wrote:
>> >
>> > If one writes a function where he moves instead of forwarding
>> >
>> >
>> >     template< typename T >
>> >     void foo(T&& value)
>> >     {
>> >       vec.push_back(std::move(value));
>> >     }
>> > **//___^
>> > That will be *The Wrong Thing* to do.
>>
>> There's nothing wrong with it, as long as you actually want to move.
>>
>> > This is because one /lies against the interface /- T&& is a forwarding
>> > reference,/by definition/.
>> >
>> > Using "object passing", /prevents/ you to lie!
>>
>> There's no such thing as a forwarding reference in the language.
>
>
> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>


Interesting.

*Question*. Given T&& being a forwarding reference, if the type T is NOT
deduced but supplied by the user AND a reference collapsing still takes
place - can this still be considered "forwarding reference"

I imagine the answer is *NO*.

*However*. A real world example:

template<class fun>
class Fn;
template<class R, class... A>
class Fn<R(A...)>
{
  using F = R (*)(void*, A...);
  template<R (*f)(A...)>
  static R stub(void*, A&&... arg)
  {
    return (*f)(std::forward<A>(arg)...);
  }
  // ... other stubs to call member functions (_p will be used then)

public:
  // ...
  template<R (*f)(A...)>
  static Fn from() noexcept
  {
    return {nullptr, &stub<f>};
  }

  // NOT forward reference, however...yeah
  R operator ()(A&&... args) const
  {
    return _f(_p, std::forward<A>(args)...);
  }

  void* _p;
  F _f;
};

In this example the operator() arguments will (need to) be "forwarding
references", though the type will not be deduced, but supplied by the user:

void func_cref(const int&) {}
void func_rref(int&&) {}

auto cb1 = Fn<void(const int&)>::from<&func_cref>(); *//< void
Fn::operator(const int& &&) const --> Fn::operator(const int&)*
auto cb2 = Fn<void(int&&)>::from<&func_rref>(); *//< void
Fn::operator(int&& &&) const --> Fn::operator(int&&)*

Effectively, we have "manual" "forwarding references".
Does the standard take these into account as such?

As Florian pointed out - metaprogramming could lead to a "forwarding
reference" "in the end".

I think that is an important question, not just for this proposal, but in
general, as teachability stand point for instance.

If we say NO, how can we explain the use of forward to a
beginner/intermediate?
If we say YES, then isn't the example in the standard somewhat incorrect by
claiming T&& is NOT a frw ref.

template <class T> struct A {
  template <class U>
    A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
                                // U&& is a forwarding reference.
  ...
};

Shouldn't the correct answer "it depends" (on the usage and instantiations
of the class)?



>
>  Using
>> T&&, where T is a template argument, for forwarding is just one use
>> case, but there are also other. For example, this syntax can be used for
>> generalization so that you don't have to write multiple overloads for
>> different argument types.
>>
>> > See a similar post from the original discussion for detailed explanation
>> >
>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>
>> Using SFINAE to force users to explicitly move is a good approach, but I
>> don't think it is always necessary. If my foo function is called, say,
>> foo_move and is properly documented, there's no reason to force users to
>> explicitly call std::move on their end. Especially, if the user is me,
>> the implementer of foo_move.
>>
>> >     Forwarding and moving a value have a fundamental difference in
>> >     strength.
>> >     Forwarding does not move the value unless permitted by the program
>> >     (i.e.
>> >     the value is assumed to be unused afterwards) while std::move is
>> >     stronger and will move even lvalue. The fact that both may end up
>> >     moving
>> >     the value does not mean they are the same and should be expressed
>> the
>> >     same way. Being more explicit about the intent is beneficial to the
>> >     developer, experienced or junior.
>> >
>> > Question is what is the original intend? And actually the intend in
>> both
>> > cases is to give the object away.
>>
>> That's from the function caller's perspective. And as far as the caller
>> is concerned, if you want to move, you use std::move. You never use
>> std::forward to move a value.
>>
>> As a function implementer (or, more accurately, receiver of the function
>> arguments), you can have different intentions wrt. the arguments. Some
>> of the arguments you may move, others forward, thirds modify or copy. My
>> point is that the compiler is not able and should not be given liberty
>> to decide which behavior to apply in each case. And the end code will
>> have better quality if this intent is apparent.
>>
>> > About the "ugliness".
>> >
>> > Well, I really hoped a simple && would do the trick, but it does clash
>> > with the binary operator && and I see no way around that.
>> >
>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>> > passin.
>>
>> These don't look any better to me, sorry. Ignoring for a moment that I
>> don't like the idea to begin with, I would prefer a function-style
>> keyword instead of new obscure operators, especially 3 or more
>> characters long.
>>
>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>> .
>>
>

--
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/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org.

------=_Part_71928_1495364448.1528536072875
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richa=
rd Smith 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"aut=
o"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:=
33 Andrey Semashev, &lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;=
;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;" h=
ref=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailt=
o=3D"e9O7oR40BQAJ">andrey....@gmail.com</a>&gt; wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On 06/08/18 09:32, <a onmousedown=3D"this.href=3D&#39;j=
avascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;=
return true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-o=
bfuscated-mailto=3D"e9O7oR40BQAJ">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%=
2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" onclick=3D"th=
is.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%2Fc%2B%2B=
draft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" href=3D"http://eel.is/=
c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=3D"nofollow">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><br></div><div>Interesting.=C2=A0</div><=
div><br></div><div><b>Question</b>. Given T&amp;&amp; being a forwarding re=
ference, if the type T is NOT deduced but supplied by the user AND a refere=
nce collapsing still takes place - can this still be considered &quot;forwa=
rding reference&quot;</div><div><br></div><div>I imagine the answer is <b>N=
O</b>.</div><div><br><b>However</b>. A real world example:=C2=A0</div><div>=
<br></div><div><font face=3D"courier new,monospace">template&lt;class fun&g=
t;<br>class Fn;</font></div><div><font face=3D"courier new,monospace">templ=
ate&lt;class R, class... A&gt;<br>class Fn&lt;R(A...)&gt;<br>{<br>=C2=A0 us=
ing F =3D R (*)(void*, A...);</font></div><div><font face=3D"courier new,mo=
nospace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static R stub(void*,=
 A&amp;&amp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return (*f)(std::for=
ward&lt;A&gt;(arg)...);<br>=C2=A0 }</font></div><div><font face=3D"courier =
new,monospace">=C2=A0 // ... other stubs to call member functions (_p will =
be used then)</font></div><div><font face=3D"courier new,monospace"><br></f=
ont></div><div><font face=3D"courier new,monospace">public:<br>=C2=A0 // ..=
..<br>=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static Fn from() noexcep=
t<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;stub&lt;f&gt;};<b=
r>=C2=A0 }<br>=C2=A0 <br>=C2=A0 // NOT forward reference, however...yeah</f=
ont></div><div><font face=3D"courier new,monospace">=C2=A0 R operator ()(A&=
amp;&amp;... args) const<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return _f(_p, st=
d::forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></div><div><font face=3D"c=
ourier new,monospace"><br>=C2=A0 void* _p;<br>=C2=A0 F _f;<br>};</font></di=
v><div><font face=3D"courier new,monospace"></font><br></div><div>In this e=
xample the operator() arguments will (need to) be &quot;forwarding referenc=
es&quot;, though the type will not be deduced, but supplied by the user:</d=
iv><div><br></div><div><font face=3D"courier new,monospace">void func_cref(=
const int&amp;) {}<br>void func_rref(int&amp;&amp;) {}</font></div><div><fo=
nt face=3D"courier new,monospace"><br></font></div><div><font face=3D"couri=
er new,monospace">auto cb1 =3D Fn&lt;void(const int&amp;)&gt;::from&lt;&amp=
;func_cref&gt;(); <i>//&lt; void Fn::operator(const int&amp; &amp;&amp;) co=
nst --&gt; Fn::operator(const int&amp;)</i><br>auto cb2 =3D Fn&lt;void(int&=
amp;&amp;)&gt;::from&lt;&amp;func_rref&gt;(); <i>//&lt; void Fn::operator(i=
nt&amp;&amp; &amp;&amp;) const --&gt; Fn::operator(int&amp;&amp;)</i></font=
></div><div><font face=3D"courier new,monospace"></font><i></i><br></div><d=
iv>Effectively, we have &quot;manual&quot; &quot;forwarding references&quot=
;.</div><div>Does the standard take these into account as such? </div><div>=
<br></div><div>As Florian pointed out - metaprogramming could lead to a &qu=
ot;forwarding reference&quot; &quot;in the end&quot;. </div><div><br></div>=
<div>I think that is an important question, not just for this proposal, but=
 in general, as teachability stand point for instance.=C2=A0</div><div><br>=
</div><div>If we say NO, how can we explain the use of forward to a beginne=
r/intermediate?</div><div>If we say YES, then isn&#39;t the example in the =
standard somewhat incorrect by claiming T&amp;&amp; is NOT a frw ref. </div=
><div><br><font face=3D"courier new,monospace">template &lt;class T&gt; str=
uct A {<br>=C2=A0 template &lt;class U&gt;<br>=C2=A0=C2=A0=C2=A0 A(T&amp;&a=
mp;, U&amp;&amp;, int*);=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 // #1: T&amp;&amp; is not a forwarding reference.<br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 // U&amp;&amp; is a forwarding reference.<br>=C2=A0 ...<=
br>};</font></div><div><font face=3D"courier new,monospace"></font><br></di=
v><div>Shouldn&#39;t the correct answer &quot;it depends&quot; (on the usag=
e and instantiations of the class)? <br></div><div><br></div><div>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"><div dir=
=3D"auto"></div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex">=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.=
org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" target=
=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"e9O7oR40BQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"e9O7oR40BQAJ">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800=
-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad2=
77-7800-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" href=3D"https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-=
35cc-16d11e1c65d9%40gmail.com" target=3D"_blank" rel=3D"nofollow">https://g=
roups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/095ad277-7800=
-53e2-<wbr>35cc-16d11e1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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/305a7701-0803-43f2-8a13-8d725122627d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803-43f2-8a13-8d725122627d=
%40isocpp.org</a>.<br />

------=_Part_71928_1495364448.1528536072875--

------=_Part_71927_1908177157.1528536072874--

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Sun, 10 Jun 2018 08:51:13 +0200
Raw View
--000000000000c8e393056e440fd7
Content-Type: text/plain; charset="UTF-8"

On Sat, 9 Jun 2018, 11:21 , <mihailnajdenov@gmail.com> wrote:

>
>
> On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>>
>> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com> wrote:
>>
>>> On 06/08/18 09:32, mihailn...@gmail.com wrote:
>>> >
>>> > If one writes a function where he moves instead of forwarding
>>> >
>>> >
>>> >     template< typename T >
>>> >     void foo(T&& value)
>>> >     {
>>> >       vec.push_back(std::move(value));
>>> >     }
>>> > **//___^
>>> > That will be *The Wrong Thing* to do.
>>>
>>> There's nothing wrong with it, as long as you actually want to move.
>>>
>>> > This is because one /lies against the interface /- T&& is a forwarding
>>> > reference,/by definition/.
>>> >
>>> > Using "object passing", /prevents/ you to lie!
>>>
>>> There's no such thing as a forwarding reference in the language.
>>
>>
>> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>>
>
>
> Interesting.
>
> *Question*. Given T&& being a forwarding reference, if the type T is NOT
> deduced but supplied by the user AND a reference collapsing still takes
> place - can this still be considered "forwarding reference"
>
> I imagine the answer is *NO*.
>

The T&& is a forwarding reference. The parameter produced by substituting
into it is not.

*However*. A real world example:
>
> template<class fun>
> class Fn;
> template<class R, class... A>
> class Fn<R(A...)>
> {
>   using F = R (*)(void*, A...);
>   template<R (*f)(A...)>
>   static R stub(void*, A&&... arg)
>   {
>     return (*f)(std::forward<A>(arg)...);
>   }
>   // ... other stubs to call member functions (_p will be used then)
>
> public:
>   // ...
>   template<R (*f)(A...)>
>   static Fn from() noexcept
>   {
>     return {nullptr, &stub<f>};
>   }
>
>   // NOT forward reference, however...yeah
>   R operator ()(A&&... args) const
>   {
>     return _f(_p, std::forward<A>(args)...);
>   }
>
>   void* _p;
>   F _f;
> };
>
> In this example the operator() arguments will (need to) be "forwarding
> references", though the type will not be deduced, but supplied by the user:
>
> void func_cref(const int&) {}
> void func_rref(int&&) {}
>
> auto cb1 = Fn<void(const int&)>::from<&func_cref>(); *//< void
> Fn::operator(const int& &&) const --> Fn::operator(const int&)*
> auto cb2 = Fn<void(int&&)>::from<&func_rref>(); *//< void
> Fn::operator(int&& &&) const --> Fn::operator(int&&)*
>
> Effectively, we have "manual" "forwarding references".
> Does the standard take these into account as such?
>

Those are not forwarding references. The point of forwarding references is
that they get special behaviour in template argument deduction (instead of
removing top-level references from both sides before deducing as is the
normal rule, for a forwarding reference deduced from an lvalue reference we
only remove the &&). Nothing else.

As Florian pointed out - metaprogramming could lead to a "forwarding
> reference" "in the end".
>
> I think that is an important question, not just for this proposal, but in
> general, as teachability stand point for instance.
>
> If we say NO, how can we explain the use of forward to a
> beginner/intermediate?
>

A beginner or intermediate is unlikely to be writing code that forwards
from something other than a function parameter.

If we say YES, then isn't the example in the standard somewhat incorrect by
> claiming T&& is NOT a frw ref.
>
> template <class T> struct A {
>   template <class U>
>     A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
>                                 // U&& is a forwarding reference.
>   ...
> };
>
> Shouldn't the correct answer "it depends" (on the usage and instantiations
> of the class)?
>

No. The T&& above never gets the special deduction behaviour. It is not a
forwarding reference.

 Using
>>> T&&, where T is a template argument, for forwarding is just one use
>>> case, but there are also other. For example, this syntax can be used for
>>> generalization so that you don't have to write multiple overloads for
>>> different argument types.
>>>
>>> > See a similar post from the original discussion for detailed
>>> explanation
>>> >
>>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>>
>>> Using SFINAE to force users to explicitly move is a good approach, but I
>>> don't think it is always necessary. If my foo function is called, say,
>>> foo_move and is properly documented, there's no reason to force users to
>>> explicitly call std::move on their end. Especially, if the user is me,
>>> the implementer of foo_move.
>>>
>>> >     Forwarding and moving a value have a fundamental difference in
>>> >     strength.
>>> >     Forwarding does not move the value unless permitted by the program
>>> >     (i.e.
>>> >     the value is assumed to be unused afterwards) while std::move is
>>> >     stronger and will move even lvalue. The fact that both may end up
>>> >     moving
>>> >     the value does not mean they are the same and should be expressed
>>> the
>>> >     same way. Being more explicit about the intent is beneficial to the
>>> >     developer, experienced or junior.
>>> >
>>> > Question is what is the original intend? And actually the intend in
>>> both
>>> > cases is to give the object away.
>>>
>>> That's from the function caller's perspective. And as far as the caller
>>> is concerned, if you want to move, you use std::move. You never use
>>> std::forward to move a value.
>>>
>>> As a function implementer (or, more accurately, receiver of the function
>>> arguments), you can have different intentions wrt. the arguments. Some
>>> of the arguments you may move, others forward, thirds modify or copy. My
>>> point is that the compiler is not able and should not be given liberty
>>> to decide which behavior to apply in each case. And the end code will
>>> have better quality if this intent is apparent.
>>>
>>> > About the "ugliness".
>>> >
>>> > Well, I really hoped a simple && would do the trick, but it does clash
>>> > with the binary operator && and I see no way around that.
>>> >
>>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>>> > passin.
>>>
>>> These don't look any better to me, sorry. Ignoring for a moment that I
>>> don't like the idea to begin with, I would prefer a function-style
>>> keyword instead of new obscure operators, especially 3 or more
>>> characters long.
>>>
>>> --
>>> 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-proposal...@isocpp.org.
>>> To post to this group, send email to std-pr...@isocpp.org.
>>> To view this discussion on the web visit
>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>>> .
>>>
>> --
> 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/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CAOfiQqn%3DTEJ-qzN48iDwJ%3D9J0UW2NkSDWgEWSq9NCZhtCCSvyA%40mail.gmail.com.

--000000000000c8e393056e440fd7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, =
9 Jun 2018, 11:21 , &lt;<a href=3D"mailto:mihailnajdenov@gmail.com">mihailn=
ajdenov@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard=
 Smith wrote:<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"auto"><div=
><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:33 Andr=
ey Semashev, &lt;<a rel=3D"nofollow noreferrer">andrey....@gmail.com</a>&gt=
; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex">On 06/08/18 09:32, <a rel=
=3D"nofollow noreferrer">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a href=3D"=
http://eel.is/c++draft/temp#deduct.call-3.sentence-3" rel=3D"nofollow noref=
errer" target=3D"_blank">http://eel.is/c++draft/temp#deduct.call-3.sentence=
-3</a><br></div></div></blockquote><div><br></div><div><br></div><div>Inter=
esting.=C2=A0</div><div><br></div><div><b>Question</b>. Given T&amp;&amp; b=
eing a forwarding reference, if the type T is NOT deduced but supplied by t=
he user AND a reference collapsing still takes place - can this still be co=
nsidered &quot;forwarding reference&quot;</div><div><br></div><div>I imagin=
e the answer is <b>NO</b>.</div></div></blockquote></div></div><div dir=3D"=
auto"><br></div><div dir=3D"auto">The T&amp;&amp; is a forwarding reference=
.. The parameter produced by substituting into it is not.</div><div dir=3D"a=
uto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div><b>However</b>. A real world example:=
=C2=A0</div><div><br></div><div><font face=3D"courier new,monospace">templa=
te&lt;class fun&gt;<br>class Fn;</font></div><div><font face=3D"courier new=
,monospace">template&lt;class R, class... A&gt;<br>class Fn&lt;R(A...)&gt;<=
br>{<br>=C2=A0 using F =3D R (*)(void*, A...);</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 st=
atic R stub(void*, A&amp;&amp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 re=
turn (*f)(std::forward&lt;A&gt;(arg)...);<br>=C2=A0 }</font></div><div><fon=
t face=3D"courier new,monospace">=C2=A0 // ... other stubs to call member f=
unctions (_p will be used then)</font></div><div><font face=3D"courier new,=
monospace"><br></font></div><div><font face=3D"courier new,monospace">publi=
c:<br>=C2=A0 // ...<br>=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static=
 Fn from() noexcept<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp=
;stub&lt;f&gt;};<br>=C2=A0 }<br>=C2=A0 <br>=C2=A0 // NOT forward reference,=
 however...yeah</font></div><div><font face=3D"courier new,monospace">=C2=
=A0 R operator ()(A&amp;&amp;... args) const<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=
=A0 return _f(_p, std::forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></div>=
<div><font face=3D"courier new,monospace"><br>=C2=A0 void* _p;<br>=C2=A0 F =
_f;<br>};</font></div><div><font face=3D"courier new,monospace"></font><br>=
</div><div>In this example the operator() arguments will (need to) be &quot=
;forwarding references&quot;, though the type will not be deduced, but supp=
lied by the user:</div><div><br></div><div><font face=3D"courier new,monosp=
ace">void func_cref(const int&amp;) {}<br>void func_rref(int&amp;&amp;) {}<=
/font></div><div><font face=3D"courier new,monospace"><br></font></div><div=
><font face=3D"courier new,monospace">auto cb1 =3D Fn&lt;void(const int&amp=
;)&gt;::from&lt;&amp;func_cref&gt;(); <i>//&lt; void Fn::operator(const int=
&amp; &amp;&amp;) const --&gt; Fn::operator(const int&amp;)</i><br>auto cb2=
 =3D Fn&lt;void(int&amp;&amp;)&gt;::from&lt;&amp;func_rref&gt;(); <i>//&lt;=
 void Fn::operator(int&amp;&amp; &amp;&amp;) const --&gt; Fn::operator(int&=
amp;&amp;)</i></font></div><div><font face=3D"courier new,monospace"></font=
><i></i><br></div><div>Effectively, we have &quot;manual&quot; &quot;forwar=
ding references&quot;.</div><div>Does the standard take these into account =
as such?</div></div></blockquote></div></div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto">Those are not forwarding references. The point of forwardin=
g references is that they get special behaviour in template argument deduct=
ion (instead of removing top-level references from both sides before deduci=
ng as is the normal rule, for a forwarding reference deduced from an lvalue=
 reference we only remove the &amp;&amp;). Nothing else.</div><div dir=3D"a=
uto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div>As Florian pointed out - metaprogramm=
ing could lead to a &quot;forwarding reference&quot; &quot;in the end&quot;=
.. </div><div><br></div><div>I think that is an important question, not just=
 for this proposal, but in general, as teachability stand point for instanc=
e.=C2=A0</div><div><br></div><div>If we say NO, how can we explain the use =
of forward to a beginner/intermediate?</div></div></blockquote></div></div>=
<div dir=3D"auto"><br></div><div dir=3D"auto">A beginner or intermediate is=
 unlikely to be writing code that forwards from something other than a func=
tion parameter.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div cla=
ss=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If =
we say YES, then isn&#39;t the example in the standard somewhat incorrect b=
y claiming T&amp;&amp; is NOT a frw ref. </div><div><br><font face=3D"couri=
er new,monospace">template &lt;class T&gt; struct A {<br>=C2=A0 template &l=
t;class U&gt;<br>=C2=A0=C2=A0=C2=A0 A(T&amp;&amp;, U&amp;&amp;, int*);=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // #1: T&amp;&amp; is n=
ot a forwarding reference.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // U&amp=
;&amp; is a forwarding reference.<br>=C2=A0 ...<br>};</font></div><div><fon=
t face=3D"courier new,monospace"></font><br></div><div>Shouldn&#39;t the co=
rrect answer &quot;it depends&quot; (on the usage and instantiations of the=
 class)?=C2=A0</div></div></blockquote></div></div><div dir=3D"auto"><br></=
div><div dir=3D"auto">No. The T&amp;&amp; above never gets the special dedu=
ction behaviour. It is not a forwarding reference.</div><div dir=3D"auto"><=
br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"auto"><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex">=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/=
Kdt1dVwL7bo/Gld277dtDQAJ" rel=3D"nofollow noreferrer" target=3D"_blank">htt=
ps://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277d=
tDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 rel=3D"nofollow noreferrer">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow noreferrer">std-pr.=
...@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/095ad277-7800-53e2-35cc-16d11e1c65d9%=
40gmail.com" rel=3D"nofollow noreferrer" target=3D"_blank">https://groups.g=
oogle.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e=
1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/305a7701-0803-43f2-8a13-8d725122627d%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org</a>.<br>
</blockquote></div></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/CAOfiQqn%3DTEJ-qzN48iDwJ%3D9J0UW2NkSD=
WgEWSq9NCZhtCCSvyA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqn%3DTE=
J-qzN48iDwJ%3D9J0UW2NkSDWgEWSq9NCZhtCCSvyA%40mail.gmail.com</a>.<br />

--000000000000c8e393056e440fd7--

.


Author: florian.csdt@gmail.com
Date: Sun, 10 Jun 2018 04:42:24 -0700 (PDT)
Raw View
------=_Part_61360_764532234.1528630945026
Content-Type: multipart/alternative;
 boundary="----=_Part_61361_15014890.1528630945027"

------=_Part_61361_15014890.1528630945027
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le dimanche 10 juin 2018 08:51:32 UTC+2, Richard Smith a =C3=A9crit :
>
> On Sat, 9 Jun 2018, 11:21 , <mihailn...@gmail.com <javascript:>> wrote:
>
>>
>>
>> On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>>>
>>> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com> wrote=
:
>>>
>>>> On 06/08/18 09:32, mihailn...@gmail.com wrote:
>>>> >=20
>>>> > If one writes a function where he moves instead of forwarding
>>>> >=20
>>>> >=20
>>>> >     template< typename T >
>>>> >     void foo(T&& value)
>>>> >     {
>>>> >       vec.push_back(std::move(value));
>>>> >     }
>>>> > **//___^
>>>> > That will be *The Wrong Thing* to do.
>>>>
>>>> There's nothing wrong with it, as long as you actually want to move.
>>>>
>>>> > This is because one /lies against the interface /- T&& is a=20
>>>> forwarding=20
>>>> > reference,/by definition/.
>>>> >=20
>>>> > Using "object passing", /prevents/ you to lie!
>>>>
>>>> There's no such thing as a forwarding reference in the language.
>>>
>>>
>>> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>>>
>>
>>
>> Interesting.=20
>>
>> *Question*. Given T&& being a forwarding reference, if the type T is NOT=
=20
>> deduced but supplied by the user AND a reference collapsing still takes=
=20
>> place - can this still be considered "forwarding reference"
>>
>> I imagine the answer is *NO*.
>>
>
> The T&& is a forwarding reference. The parameter produced by substituting=
=20
> into it is not.
>
> *However*. A real world example:=20
>>
>> template<class fun>
>> class Fn;
>> template<class R, class... A>
>> class Fn<R(A...)>
>> {
>>   using F =3D R (*)(void*, A...);
>>   template<R (*f)(A...)>
>>   static R stub(void*, A&&... arg)
>>   {
>>     return (*f)(std::forward<A>(arg)...);
>>   }
>>   // ... other stubs to call member functions (_p will be used then)
>>
>> public:
>>   // ...
>>   template<R (*f)(A...)>
>>   static Fn from() noexcept
>>   {
>>     return {nullptr, &stub<f>};
>>   }
>>  =20
>>   // NOT forward reference, however...yeah
>>   R operator ()(A&&... args) const
>>   {
>>     return _f(_p, std::forward<A>(args)...);
>>   }
>>
>>   void* _p;
>>   F _f;
>> };
>>
>> In this example the operator() arguments will (need to) be "forwarding=
=20
>> references", though the type will not be deduced, but supplied by the us=
er:
>>
>> void func_cref(const int&) {}
>> void func_rref(int&&) {}
>>
>> auto cb1 =3D Fn<void(const int&)>::from<&func_cref>(); *//< void=20
>> Fn::operator(const int& &&) const --> Fn::operator(const int&)*
>> auto cb2 =3D Fn<void(int&&)>::from<&func_rref>(); *//< void=20
>> Fn::operator(int&& &&) const --> Fn::operator(int&&)*
>>
>> Effectively, we have "manual" "forwarding references".
>> Does the standard take these into account as such?
>>
>
> Those are not forwarding references. The point of forwarding references i=
s=20
> that they get special behaviour in template argument deduction (instead o=
f=20
> removing top-level references from both sides before deducing as is the=
=20
> normal rule, for a forwarding reference deduced from an lvalue reference =
we=20
> only remove the &&). Nothing else.
>
> As Florian pointed out - metaprogramming could lead to a "forwarding=20
>> reference" "in the end".=20
>>
>> I think that is an important question, not just for this proposal, but i=
n=20
>> general, as teachability stand point for instance.=20
>>
>> If we say NO, how can we explain the use of forward to a=20
>> beginner/intermediate?
>>
>
> A beginner or intermediate is unlikely to be writing code that forwards=
=20
> from something other than a function parameter.
>
> If we say YES, then isn't the example in the standard somewhat incorrect=
=20
>> by claiming T&& is NOT a frw ref.=20
>>
>> template <class T> struct A {
>>   template <class U>
>>     A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference=
..
>>                                 // U&& is a forwarding reference.
>>   ...
>> };
>>
>> Shouldn't the correct answer "it depends" (on the usage and=20
>> instantiations of the class)?=20
>>
>
> No. The T&& above never gets the special deduction behaviour. It is not a=
=20
> forwarding reference.
>

Here T&& is not a "forwarding" reference while U&& is, this is perfectly=20
true.
But there is no reason they could behave differently when used (meaning=20
they yield the same type).
The only difference here is: T is not deduced while U is. All the rest=20
should be exactly the same (if they yield the same type of course).
In fact T might be deduced by another function and being passed as is to=20
this class where it cannot be a forwarding reference (because no deducing=
=20
step is performed on it), but should have all the exact same properties as=
=20
a "proper" forwarding reference (whatever that means).

In addition, even T in this example could be deduced at the same point as U=
:
template <class T>
struct Foo {
  template <class U>
  Foo(T&&, U&&);
};

Foo(1, 2); // both T and U are deduced here

With class template deduction introduced in C++17, the above code makes=20
both T and U deducible at the same point, but nobody would think T and U=20
behave differently here: T can also be a "forwarding" reference here.
Even worse:
Foo(1, 2); // T deduced to int: should behave like a forwarding reference,=
=20
like U
Foo<int>(1, 2); // T not deduced: could behave differently? but this is the=
=20
exact same type, how could it be?

So no, the special rules of "forwarding" references should not go further=
=20
than deduction. After deduction, you should not have any difference between=
=20
a forwarding reference, a deduced type that is not a forwarding reference=
=20
and a not deduced type as long as they give the same type.
The type system is oblivious to template parameter deduction, and should=20
remain like this. (the opposite is obviously not true)

--=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/f22ecfc3-b56c-46ef-95f9-b67185ebaf7a%40isocpp.or=
g.

------=_Part_61361_15014890.1528630945027
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 08:51:32 UTC+2, Richard S=
mith a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, 9 Jun =
2018, 11:21 , &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-=
mailto=3D"FnahVpayBQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;ja=
vascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;r=
eturn true;">mihailn...@gmail.com</a>&gt; wrote:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 P=
M UTC+3, Richard Smith wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div d=
ir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun =
2018, 10:33 Andrey Semashev, &lt;<a rel=3D"nofollow noreferrer">andrey....@=
gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 06/08=
/18 09:32, <a rel=3D"nofollow noreferrer">mihailn...@gmail.com</a> wrote:<b=
r>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a href=3D"=
http://eel.is/c++draft/temp#deduct.call-3.sentence-3" rel=3D"nofollow" targ=
et=3D"_blank" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x=
3dhttp%3A%2F%2Feel.is%2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;retur=
n true;" onclick=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A=
%2F%2Feel.is%2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x2=
6sntz\x3d1\x26usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><br></div><div>Interesting.=C2=A0</div><=
div><br></div><div><b>Question</b>. Given T&amp;&amp; being a forwarding re=
ference, if the type T is NOT deduced but supplied by the user AND a refere=
nce collapsing still takes place - can this still be considered &quot;forwa=
rding reference&quot;</div><div><br></div><div>I imagine the answer is <b>N=
O</b>.</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div=
 dir=3D"auto">The T&amp;&amp; is a forwarding reference. The parameter prod=
uced by substituting into it is not.</div><div dir=3D"auto"><br></div><div =
dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div><b>However</b>. A real world example:=C2=A0</div><div><br=
></div><div><font face=3D"courier new,monospace">template&lt;class fun&gt;<=
br>class Fn;</font></div><div><font face=3D"courier new,monospace">template=
&lt;class R, class... A&gt;<br>class Fn&lt;R(A...)&gt;<br>{<br>=C2=A0 using=
 F =3D R (*)(void*, A...);</font></div><div><font face=3D"courier new,monos=
pace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static R stub(void*, A&=
amp;&amp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return (*f)(std::forwar=
d&lt;A&gt;(arg)...);<br>=C2=A0 }</font></div><div><font face=3D"courier new=
,monospace">=C2=A0 // ... other stubs to call member functions (_p will be =
used then)</font></div><div><font face=3D"courier new,monospace"><br></font=
></div><div><font face=3D"courier new,monospace">public:<br>=C2=A0 // ...<b=
r>=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static Fn from() noexcept<b=
r>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;stub&lt;f&gt;};<br>=
=C2=A0 }<br>=C2=A0 <br>=C2=A0 // NOT forward reference, however...yeah</fon=
t></div><div><font face=3D"courier new,monospace">=C2=A0 R operator ()(A&am=
p;&amp;... args) const<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return _f(_p, std:=
:forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></div><div><font face=3D"cou=
rier new,monospace"><br>=C2=A0 void* _p;<br>=C2=A0 F _f;<br>};</font></div>=
<div><font face=3D"courier new,monospace"></font><br></div><div>In this exa=
mple the operator() arguments will (need to) be &quot;forwarding references=
&quot;, though the type will not be deduced, but supplied by the user:</div=
><div><br></div><div><font face=3D"courier new,monospace">void func_cref(co=
nst int&amp;) {}<br>void func_rref(int&amp;&amp;) {}</font></div><div><font=
 face=3D"courier new,monospace"><br></font></div><div><font face=3D"courier=
 new,monospace">auto cb1 =3D Fn&lt;void(const int&amp;)&gt;::from&lt;&amp;f=
unc_cref&gt;(); <i>//&lt; void Fn::operator(const int&amp; &amp;&amp;) cons=
t --&gt; Fn::operator(const int&amp;)</i><br>auto cb2 =3D Fn&lt;void(int&am=
p;&amp;)&gt;::from&lt;&amp;func_<wbr>rref&gt;(); <i>//&lt; void Fn::operato=
r(int&amp;&amp; &amp;&amp;) const --&gt; Fn::operator(int&amp;&amp;)</i></f=
ont></div><div><font face=3D"courier new,monospace"></font><i></i><br></div=
><div>Effectively, we have &quot;manual&quot; &quot;forwarding references&q=
uot;.</div><div>Does the standard take these into account as such?</div></d=
iv></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">T=
hose are not forwarding references. The point of forwarding references is t=
hat they get special behaviour in template argument deduction (instead of r=
emoving top-level references from both sides before deducing as is the norm=
al rule, for a forwarding reference deduced from an lvalue reference we onl=
y remove the &amp;&amp;). Nothing else.</div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr"><div>As Florian pointed out - metaprogramming could lead to=
 a &quot;forwarding reference&quot; &quot;in the end&quot;. </div><div><br>=
</div><div>I think that is an important question, not just for this proposa=
l, but in general, as teachability stand point for instance.=C2=A0</div><di=
v><br></div><div>If we say NO, how can we explain the use of forward to a b=
eginner/intermediate?</div></div></blockquote></div></div><div dir=3D"auto"=
><br></div><div dir=3D"auto">A beginner or intermediate is unlikely to be w=
riting code that forwards from something other than a function parameter.</=
div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If we say YES, then =
isn&#39;t the example in the standard somewhat incorrect by claiming T&amp;=
&amp; is NOT a frw ref. </div><div><br><font face=3D"courier new,monospace"=
>template &lt;class T&gt; struct A {<br>=C2=A0 template &lt;class U&gt;<br>=
=C2=A0=C2=A0=C2=A0 A(T&amp;&amp;, U&amp;&amp;, int*);=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // #1: T&amp;&amp; is not a forwarding re=
ference.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<wbr>=C2=A0 // U&amp;&amp; is a f=
orwarding reference.<br>=C2=A0 ...<br>};</font></div><div><font face=3D"cou=
rier new,monospace"></font><br></div><div>Shouldn&#39;t the correct answer =
&quot;it depends&quot; (on the usage and instantiations of the class)?=C2=
=A0</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div di=
r=3D"auto">No. The T&amp;&amp; above never gets the special deduction behav=
iour. It is not a forwarding reference.</div></div></blockquote><div><br></=
div><div>Here T&amp;&amp; is not a &quot;forwarding&quot; reference while U=
&amp;&amp; is, this is perfectly true.</div><div>But there is no reason the=
y could behave differently when used (meaning they yield the same type).</d=
iv><div>The only difference here is: T is not deduced while U is. All the r=
est should be exactly the same (if they yield the same type of course).<br>=
</div><div>In fact T might be deduced by another function and being passed =
as is to this class where it cannot be a forwarding reference (because no d=
educing step is performed on it), but should have all the exact same proper=
ties as a &quot;proper&quot; forwarding reference (whatever that means).<br=
></div><div><br></div><div>In addition, even T in this example could be ded=
uced at the same point as U:<br></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-prettify">template</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">struct<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> U</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> U</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;&amp;);</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #606;" cla=
ss=3D"styled-by-prettify">Foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">1</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: #066;" class=3D"styled-by-prettify">2</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// both T and U are deduced here</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div></div><div><br></div><div>With class template deduction introduced=
 in C++17, the above code makes both T and U deducible at the same point, b=
ut nobody would think T and U behave differently here: T can also be a &quo=
t;forwarding&quot; reference here.<br></div><div>Even worse:</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"subprettypr=
int"><span style=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">1</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: #066;" class=3D"=
styled-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// T d=
educed to int: should behave like a forwarding reference, like U</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pret=
tify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">// T not deduced: co=
uld behave differently? but this is the exact same type, how could it be?</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
/div></code></div><br>So no, the special rules of &quot;forwarding&quot; re=
ferences should not go further than deduction. After deduction, you should =
not have any difference between a forwarding reference, a deduced type that=
 is not a forwarding reference and a not deduced type as long as they give =
the same type.</div><div>The type system is oblivious to template parameter=
 deduction, and should remain like this. (the opposite is obviously not tru=
e)<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/f22ecfc3-b56c-46ef-95f9-b67185ebaf7a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f22ecfc3-b56c-46ef-95f9-b67185ebaf7a=
%40isocpp.org</a>.<br />

------=_Part_61361_15014890.1528630945027--

------=_Part_61360_764532234.1528630945026--

.


Author: mihailnajdenov@gmail.com
Date: Sun, 10 Jun 2018 05:23:37 -0700 (PDT)
Raw View
------=_Part_87419_1914685308.1528633418019
Content-Type: multipart/alternative;
 boundary="----=_Part_87420_325587996.1528633418020"

------=_Part_87420_325587996.1528633418020
Content-Type: text/plain; charset="UTF-8"

Ok, now it is all clear.

The problem is forward is used not only to pass along a forward reference,
but also as to tool to trigger reference collapsing.

Now the question is should a unified operator also being able to do that. I
think the answer is YES - after all it is intended to be a drop-in
replacement for both forward and move, no matter the use case.


And I think it is actually simpler then initially thought.


The heuristic is as follows - IFF an identifier is a lvalue reference -
"move", in all other cases "forward".
This might sound counterintuitive, but, given current language rules - it
woks in all cases.


Lets take look at poor-mans implementation an operator named "give".

#define give(x) static_cast<decltype(x)&&>(x)
#define giveref(x) static_cast<std::remove_reference_t<decltype(x)>&&>(x)

(In a real implementation they will be called the same and the compiler
will pick the correct implementation.)


Now given our overloads

void f(C& ) { std::cout<<__PRETTY_FUNCTION__; }
void f(const C& ) { std::cout<<__PRETTY_FUNCTION__; }
void f(C&& ) { std::cout<<__PRETTY_FUNCTION__; }
void f(const C&& ) { std::cout<<__PRETTY_FUNCTION__; }

We want to have always the correct one called, as if the user correctly
used forward or move

void f1(C& c) { f(giveref(c)); }
void f1(const C& c) { f(giveref(c)); }
void f1(C&& c) { f(give(c)); }
void f1(const C&& c) { f(give(c)); }

void f2(C c) { f(give(c)); }

template<class T>
void f3(T&& c) { f(give(c)); }

template<class T>
void f4(const T&& c) { f(give(c)); }

template <class T> //< argument used as function reference argument:
wrap<const Type&>
struct warp
{
  void operator()(T&& c) { f(give(c)); }
};

All these work correctly, and as you can see, only in very few places we
need the alternative implementation.

The only places where the baseline give impl will not work is when we need
to move a lvalue reference, so all the compiler needs to do is to detect
that case issue the correct implementation.

As a result we will have no-brainer object passing - calling &&> on an
identifier will *always* work correctly either moving (casting) or
forwarding (reference collapsing).

That's it.


On Sunday, June 10, 2018 at 9:51:32 AM UTC+3, Richard Smith wrote:

> On Sat, 9 Jun 2018, 11:21 , <mihailn...@gmail.com <javascript:>> wrote:
>
>>
>>
>> On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Richard Smith wrote:
>>>
>>> On Fri, 8 Jun 2018, 10:33 Andrey Semashev, <andrey....@gmail.com> wrote:
>>>
>>>> On 06/08/18 09:32, mihailn...@gmail.com wrote:
>>>> >
>>>> > If one writes a function where he moves instead of forwarding
>>>> >
>>>> >
>>>> >     template< typename T >
>>>> >     void foo(T&& value)
>>>> >     {
>>>> >       vec.push_back(std::move(value));
>>>> >     }
>>>> > **//___^
>>>> > That will be *The Wrong Thing* to do.
>>>>
>>>> There's nothing wrong with it, as long as you actually want to move.
>>>>
>>>> > This is because one /lies against the interface /- T&& is a
>>>> forwarding
>>>> > reference,/by definition/.
>>>> >
>>>> > Using "object passing", /prevents/ you to lie!
>>>>
>>>> There's no such thing as a forwarding reference in the language.
>>>
>>>
>>> http://eel.is/c++draft/temp#deduct.call-3.sentence-3
>>>
>>
>>
>> Interesting.
>>
>> *Question*. Given T&& being a forwarding reference, if the type T is NOT
>> deduced but supplied by the user AND a reference collapsing still takes
>> place - can this still be considered "forwarding reference"
>>
>> I imagine the answer is *NO*.
>>
>
> The T&& is a forwarding reference. The parameter produced by substituting
> into it is not.
>
> *However*. A real world example:
>>
>> template<class fun>
>> class Fn;
>> template<class R, class... A>
>> class Fn<R(A...)>
>> {
>>   using F = R (*)(void*, A...);
>>   template<R (*f)(A...)>
>>   static R stub(void*, A&&... arg)
>>   {
>>     return (*f)(std::forward<A>(arg)...);
>>   }
>>   // ... other stubs to call member functions (_p will be used then)
>>
>> public:
>>   // ...
>>   template<R (*f)(A...)>
>>   static Fn from() noexcept
>>   {
>>     return {nullptr, &stub<f>};
>>   }
>>
>>   // NOT forward reference, however...yeah
>>   R operator ()(A&&... args) const
>>   {
>>     return _f(_p, std::forward<A>(args)...);
>>   }
>>
>>   void* _p;
>>   F _f;
>> };
>>
>> In this example the operator() arguments will (need to) be "forwarding
>> references", though the type will not be deduced, but supplied by the user:
>>
>> void func_cref(const int&) {}
>> void func_rref(int&&) {}
>>
>> auto cb1 = Fn<void(const int&)>::from<&func_cref>(); *//< void
>> Fn::operator(const int& &&) const --> Fn::operator(const int&)*
>> auto cb2 = Fn<void(int&&)>::from<&func_rref>(); *//< void
>> Fn::operator(int&& &&) const --> Fn::operator(int&&)*
>>
>> Effectively, we have "manual" "forwarding references".
>> Does the standard take these into account as such?
>>
>
> Those are not forwarding references. The point of forwarding references is
> that they get special behaviour in template argument deduction (instead of
> removing top-level references from both sides before deducing as is the
> normal rule, for a forwarding reference deduced from an lvalue reference we
> only remove the &&). Nothing else.
>
> As Florian pointed out - metaprogramming could lead to a "forwarding
>> reference" "in the end".
>>
>> I think that is an important question, not just for this proposal, but in
>> general, as teachability stand point for instance.
>>
>> If we say NO, how can we explain the use of forward to a
>> beginner/intermediate?
>>
>
> A beginner or intermediate is unlikely to be writing code that forwards
> from something other than a function parameter.
>
> If we say YES, then isn't the example in the standard somewhat incorrect
>> by claiming T&& is NOT a frw ref.
>>
>> template <class T> struct A {
>>   template <class U>
>>     A(T&&, U&&, int*);          // #1: T&& is not a forwarding reference.
>>                                 // U&& is a forwarding reference.
>>   ...
>> };
>>
>> Shouldn't the correct answer "it depends" (on the usage and
>> instantiations of the class)?
>>
>
> No. The T&& above never gets the special deduction behaviour. It is not a
> forwarding reference.
>
>  Using
>>>> T&&, where T is a template argument, for forwarding is just one use
>>>> case, but there are also other. For example, this syntax can be used
>>>> for
>>>> generalization so that you don't have to write multiple overloads for
>>>> different argument types.
>>>>
>>>> > See a similar post from the original discussion for detailed
>>>> explanation
>>>> >
>>>> https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ
>>>>
>>>> Using SFINAE to force users to explicitly move is a good approach, but
>>>> I
>>>> don't think it is always necessary. If my foo function is called, say,
>>>> foo_move and is properly documented, there's no reason to force users
>>>> to
>>>> explicitly call std::move on their end. Especially, if the user is me,
>>>> the implementer of foo_move.
>>>>
>>>> >     Forwarding and moving a value have a fundamental difference in
>>>> >     strength.
>>>> >     Forwarding does not move the value unless permitted by the program
>>>> >     (i.e.
>>>> >     the value is assumed to be unused afterwards) while std::move is
>>>> >     stronger and will move even lvalue. The fact that both may end up
>>>> >     moving
>>>> >     the value does not mean they are the same and should be expressed
>>>> the
>>>> >     same way. Being more explicit about the intent is beneficial to
>>>> the
>>>> >     developer, experienced or junior.
>>>> >
>>>> > Question is what is the original intend? And actually the intend in
>>>> both
>>>> > cases is to give the object away.
>>>>
>>>> That's from the function caller's perspective. And as far as the caller
>>>> is concerned, if you want to move, you use std::move. You never use
>>>> std::forward to move a value.
>>>>
>>>> As a function implementer (or, more accurately, receiver of the
>>>> function
>>>> arguments), you can have different intentions wrt. the arguments. Some
>>>> of the arguments you may move, others forward, thirds modify or copy.
>>>> My
>>>> point is that the compiler is not able and should not be given liberty
>>>> to decide which behavior to apply in each case. And the end code will
>>>> have better quality if this intent is apparent.
>>>>
>>>> > About the "ugliness".
>>>> >
>>>> > Well, I really hoped a simple && would do the trick, but it does
>>>> clash
>>>> > with the binary operator && and I see no way around that.
>>>> >
>>>> > An alternative might be val~~ or val~&& or just val~ or a keyword val
>>>> > passin.
>>>>
>>>> These don't look any better to me, sorry. Ignoring for a moment that I
>>>> don't like the idea to begin with, I would prefer a function-style
>>>> keyword instead of new obscure operators, especially 3 or more
>>>> characters long.
>>>>
>>>> --
>>>> 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-proposal...@isocpp.org.
>>>> To post to this group, send email to std-pr...@isocpp.org.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-35cc-16d11e1c65d9%40gmail.com
>>>> .
>>>>
>>> --
>> 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-proposal...@isocpp.org <javascript:>.
>> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
>> To view this discussion on the web visit
>> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803-43f2-8a13-8d725122627d%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
>

--
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/23f11e4d-ed7d-4e12-8c92-3ec900edd692%40isocpp.org.

------=_Part_87420_325587996.1528633418020
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Ok, now it is all clear.</div><div><br></div><div>The=
 problem is forward is used not only to pass along a forward reference, but=
 also as to tool to trigger reference collapsing.=C2=A0</div><div><br></div=
><div>Now the question is should a unified operator also being able to do t=
hat. I think the answer is YES - after all it is intended to be a drop-in r=
eplacement for both forward and move, no matter the use case.</div><div><br=
></div><div><br>And I think it is actually simpler then initially thought.<=
/div><div><br></div><div><br></div><div>The heuristic is as follows - IFF a=
n identifier is a lvalue reference - &quot;move&quot;, in all other cases &=
quot;forward&quot;. </div><div>This might sound counterintuitive, but, give=
n current language rules - it woks in all cases.</div><div><br></div><div><=
br></div><div>Lets take look at poor-mans implementation an operator named =
&quot;give&quot;.=C2=A0</div><div><br></div><div><font face=3D"courier new,=
monospace">#define give(x) static_cast&lt;decltype(x)&amp;&amp;&gt;(x)<br>#=
define giveref(x) static_cast&lt;std::remove_reference_t&lt;decltype(x)&gt;=
&amp;&amp;&gt;(x)</font></div><div><font face=3D"courier new,monospace"><br=
></font></div><div>(In a real implementation they will be called the same a=
nd the compiler will pick the correct implementation.)</div><div><br></div>=
<div><br></div><div>Now given our overloads</div><div><br></div><div><font =
face=3D"courier new,monospace">void f(C&amp; ) { std::cout&lt;&lt;__PRETTY_=
FUNCTION__; }<br>void f(const C&amp; ) { std::cout&lt;&lt;__PRETTY_FUNCTION=
__; }<br>void f(C&amp;&amp; ) { std::cout&lt;&lt;__PRETTY_FUNCTION__; }<br>=
void f(const C&amp;&amp; ) { std::cout&lt;&lt;__PRETTY_FUNCTION__; }=C2=A0<=
/font></div><div><font face=3D"courier new,monospace"><br></font></div><div=
><font face=3D"arial,sans-serif">We want to have always the correct one cal=
led, as if the user correctly used forward or move</font></div><div><font f=
ace=3D"arial,sans-serif"><br></font></div><div><font face=3D"courier new,mo=
nospace">void f1(C&amp; c) { f(giveref(c)); }<br>void f1(const C&amp; c) { =
f(giveref(c)); }</font></div><div><font face=3D"courier new,monospace">void=
 f1(C&amp;&amp; c) { f(give(c)); }<br><div>void f1(const C&amp;&amp; c) { f=
(give(c)); }</div><div><br></div><div>void f2(C c) { f(give(c)); }</div><di=
v><br></div>template&lt;class T&gt;<br><div>void f3(T&amp;&amp; c) { f(give=
(c)); }</div><div><br></div>template&lt;class T&gt;<br><div>void f4(const T=
&amp;&amp; c) { f(give(c)); }</div><div><br></div>template &lt;class T&gt; =
//&lt; argument used as function reference argument: wrap&lt;const Type&amp=
;&gt;<br>struct warp <br>{<br>=C2=A0 void operator()(T&amp;&amp; c) { f(giv=
e(c)); } <br>};</font></div><div><font face=3D"courier new,monospace"></fon=
t><br></div><div>All these work correctly, and as you can see, only in very=
 few places we need the alternative implementation.</div><div><br></div><di=
v>The only places where the baseline give impl will not work is when we nee=
d to move a lvalue reference, so all the compiler needs to do is to detect =
that case issue the correct implementation.</div><div><br></div><div>As a r=
esult we will have no-brainer object passing - calling &amp;&amp;&gt; on an=
 identifier will <i>always</i> work correctly either moving (casting) or fo=
rwarding (reference collapsing).=C2=A0</div><div><br></div><div>That&#39;s =
it. <br><br><br>On Sunday, June 10, 2018 at 9:51:32 AM UTC+3, Richard Smith=
 wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"auto"=
><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, 9 Jun 2018, 11:21=
 , &lt;<a onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" on=
click=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascript=
:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"FnahVpayBQAJ=
">mihailn...@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><br><br>On Friday, June 8, 2018 at 7:13:59 PM UTC+3, Ri=
chard Smith wrote:<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"auto"=
><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Fri, 8 Jun 2018, 10:33=
 Andrey Semashev, &lt;<a rel=3D"nofollow noreferrer">andrey....@gmail.com</=
a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 06/08/18 09:32, <a=
 rel=3D"nofollow noreferrer">mihailn...@gmail.com</a> wrote:<br>
&gt; <br>
&gt; If one writes a function where he moves instead of forwarding<br>
&gt; <br>
&gt; <br>
&gt;=C2=A0 =C2=A0=C2=A0=C2=A0template&lt; typename T &gt;<br>
&gt;=C2=A0 =C2=A0 =C2=A0void foo(T&amp;&amp; value)<br>
&gt;=C2=A0 =C2=A0 =C2=A0{<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0vec.push_back(std::move(<wbr>value));<br>
&gt;=C2=A0 =C2=A0 =C2=A0}<br>
&gt; **//___^<br>
&gt; That will be *The Wrong Thing* to do.<br>
<br>
There&#39;s nothing wrong with it, as long as you actually want to move.<br=
>
<br>
&gt; This is because one /lies against the interface /- T&amp;&amp; is a fo=
rwarding <br>
&gt; reference,/by definition/.<br>
&gt; <br>
&gt; Using &quot;object passing&quot;, /prevents/ you to lie!<br>
<br>
There&#39;s no such thing as a forwarding reference in the language.</block=
quote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto"><a onmoused=
own=3D"this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%=
2Fc%2B%2Bdraft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x2=
6usg\x3dAFQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" onclick=3D"th=
is.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Feel.is%2Fc%2B%2B=
draft%2Ftemp%23deduct.call-3.sentence-3\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dA=
FQjCNGwIqEZk0BiqHf4iL-LevhlD944yg&#39;;return true;" href=3D"http://eel.is/=
c++draft/temp#deduct.call-3.sentence-3" target=3D"_blank" rel=3D"nofollow">=
http://eel.is/c++draft/temp#<wbr>deduct.call-3.sentence-3</a><br></div></di=
v></blockquote><div><br></div><div><br></div><div>Interesting.=C2=A0</div><=
div><br></div><div><b>Question</b>. Given T&amp;&amp; being a forwarding re=
ference, if the type T is NOT deduced but supplied by the user AND a refere=
nce collapsing still takes place - can this still be considered &quot;forwa=
rding reference&quot;</div><div><br></div><div>I imagine the answer is <b>N=
O</b>.</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div=
 dir=3D"auto">The T&amp;&amp; is a forwarding reference. The parameter prod=
uced by substituting into it is not.</div><div dir=3D"auto"><br></div><div =
dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div><b>However</b>. A real world example:=C2=A0</div><div><br=
></div><div><font face=3D"courier new,monospace">template&lt;class fun&gt;<=
br>class Fn;</font></div><div><font face=3D"courier new,monospace">template=
&lt;class R, class... A&gt;<br>class Fn&lt;R(A...)&gt;<br>{<br>=C2=A0 using=
 F =3D R (*)(void*, A...);</font></div><div><font face=3D"courier new,monos=
pace">=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static R stub(void*, A&=
amp;&amp;... arg)<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return (*f)(std::forwar=
d&lt;A&gt;(arg)...);<br>=C2=A0 }</font></div><div><font face=3D"courier new=
,monospace">=C2=A0 // ... other stubs to call member functions (_p will be =
used then)</font></div><div><font face=3D"courier new,monospace"><br></font=
></div><div><font face=3D"courier new,monospace">public:<br>=C2=A0 // ...<b=
r>=C2=A0 template&lt;R (*f)(A...)&gt;<br>=C2=A0 static Fn from() noexcept<b=
r>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return {nullptr, &amp;stub&lt;f&gt;};<br>=
=C2=A0 }<br>=C2=A0 <br>=C2=A0 // NOT forward reference, however...yeah</fon=
t></div><div><font face=3D"courier new,monospace">=C2=A0 R operator ()(A&am=
p;&amp;... args) const<br>=C2=A0 {<br>=C2=A0=C2=A0=C2=A0 return _f(_p, std:=
:forward&lt;A&gt;(args)...);<br>=C2=A0 }</font></div><div><font face=3D"cou=
rier new,monospace"><br>=C2=A0 void* _p;<br>=C2=A0 F _f;<br>};</font></div>=
<div><font face=3D"courier new,monospace"></font><br></div><div>In this exa=
mple the operator() arguments will (need to) be &quot;forwarding references=
&quot;, though the type will not be deduced, but supplied by the user:</div=
><div><br></div><div><font face=3D"courier new,monospace">void func_cref(co=
nst int&amp;) {}<br>void func_rref(int&amp;&amp;) {}</font></div><div><font=
 face=3D"courier new,monospace"><br></font></div><div><font face=3D"courier=
 new,monospace">auto cb1 =3D Fn&lt;void(const int&amp;)&gt;::from&lt;&amp;f=
unc_cref&gt;(); <i>//&lt; void Fn::operator(const int&amp; &amp;&amp;) cons=
t --&gt; Fn::operator(const int&amp;)</i><br>auto cb2 =3D Fn&lt;void(int&am=
p;&amp;)&gt;::from&lt;&amp;func_<wbr>rref&gt;(); <i>//&lt; void Fn::operato=
r(int&amp;&amp; &amp;&amp;) const --&gt; Fn::operator(int&amp;&amp;)</i></f=
ont></div><div><font face=3D"courier new,monospace"></font><i></i><br></div=
><div>Effectively, we have &quot;manual&quot; &quot;forwarding references&q=
uot;.</div><div>Does the standard take these into account as such?</div></d=
iv></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">T=
hose are not forwarding references. The point of forwarding references is t=
hat they get special behaviour in template argument deduction (instead of r=
emoving top-level references from both sides before deducing as is the norm=
al rule, for a forwarding reference deduced from an lvalue reference we onl=
y remove the &amp;&amp;). Nothing else.</div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr"><div>As Florian pointed out - metaprogramming could lead to=
 a &quot;forwarding reference&quot; &quot;in the end&quot;. </div><div><br>=
</div><div>I think that is an important question, not just for this proposa=
l, but in general, as teachability stand point for instance.=C2=A0</div><di=
v><br></div><div>If we say NO, how can we explain the use of forward to a b=
eginner/intermediate?</div></div></blockquote></div></div><div dir=3D"auto"=
><br></div><div dir=3D"auto">A beginner or intermediate is unlikely to be w=
riting code that forwards from something other than a function parameter.</=
div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>If we say YES, then =
isn&#39;t the example in the standard somewhat incorrect by claiming T&amp;=
&amp; is NOT a frw ref. </div><div><br><font face=3D"courier new,monospace"=
>template &lt;class T&gt; struct A {<br>=C2=A0 template &lt;class U&gt;<br>=
=C2=A0=C2=A0=C2=A0 A(T&amp;&amp;, U&amp;&amp;, int*);=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // #1: T&amp;&amp; is not a forwarding re=
ference.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<wbr>=C2=A0 // U&amp;&amp; is a f=
orwarding reference.<br>=C2=A0 ...<br>};</font></div><div><font face=3D"cou=
rier new,monospace"></font><br></div><div>Shouldn&#39;t the correct answer =
&quot;it depends&quot; (on the usage and instantiations of the class)?=C2=
=A0</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div di=
r=3D"auto">No. The T&amp;&amp; above never gets the special deduction behav=
iour. It is not a forwarding reference.</div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><=
div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
=C2=A0Using<br>
T&amp;&amp;, where T is a template argument, for forwarding is just one use=
 <br>
case, but there are also other. For example, this syntax can be used for <b=
r>
generalization so that you don&#39;t have to write multiple overloads for <=
br>
different argument types.<br>
<br>
&gt; See a similar post from the original discussion for detailed explanati=
on<br>
&gt; <a onmousedown=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.=
org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" onclick=
=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-propo=
sals/Kdt1dVwL7bo/Gld277dtDQAJ&#39;;return true;" href=3D"https://groups.goo=
gle.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/Gld277dtDQAJ" target=
=3D"_blank" rel=3D"nofollow">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>proposals/Kdt1dVwL7bo/<wbr>Gld277dtDQAJ</a><br>
<br>
Using SFINAE to force users to explicitly move is a good approach, but I <b=
r>
don&#39;t think it is always necessary. If my foo function is called, say, =
<br>
foo_move and is properly documented, there&#39;s no reason to force users t=
o <br>
explicitly call std::move on their end. Especially, if the user is me, <br>
the implementer of foo_move.<br>
<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding and moving a value have a fundamental di=
fference in<br>
&gt;=C2=A0 =C2=A0 =C2=A0strength.<br>
&gt;=C2=A0 =C2=A0 =C2=A0Forwarding does not move the value unless permitted=
 by the program<br>
&gt;=C2=A0 =C2=A0 =C2=A0(i.e.<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value is assumed to be unused afterwards) while=
 std::move is<br>
&gt;=C2=A0 =C2=A0 =C2=A0stronger and will move even lvalue. The fact that b=
oth may end up<br>
&gt;=C2=A0 =C2=A0 =C2=A0moving<br>
&gt;=C2=A0 =C2=A0 =C2=A0the value does not mean they are the same and shoul=
d be expressed the<br>
&gt;=C2=A0 =C2=A0 =C2=A0same way. Being more explicit about the intent is b=
eneficial to the<br>
&gt;=C2=A0 =C2=A0 =C2=A0developer, experienced or junior.<br>
&gt; <br>
&gt; Question is what is the original intend? And actually the intend in bo=
th <br>
&gt; cases is to give the object away.<br>
<br>
That&#39;s from the function caller&#39;s perspective. And as far as the ca=
ller <br>
is concerned, if you want to move, you use std::move. You never use <br>
std::forward to move a value.<br>
<br>
As a function implementer (or, more accurately, receiver of the function <b=
r>
arguments), you can have different intentions wrt. the arguments. Some <br>
of the arguments you may move, others forward, thirds modify or copy. My <b=
r>
point is that the compiler is not able and should not be given liberty <br>
to decide which behavior to apply in each case. And the end code will <br>
have better quality if this intent is apparent.<br>
<br>
&gt; About the &quot;ugliness&quot;.<br>
&gt; <br>
&gt; Well, I really hoped a simple &amp;&amp; would do the trick, but it do=
es clash <br>
&gt; with the binary operator &amp;&amp; and I see no way around that.<br>
&gt; <br>
&gt; An alternative might be val~~ or val~&amp;&amp; or just val~ or a keyw=
ord val <br>
&gt; passin.<br>
<br>
These don&#39;t look any better to me, sorry. Ignoring for a moment that I =
<br>
don&#39;t like the idea to begin with, I would prefer a function-style <br>
keyword instead of new obscure operators, especially 3 or more <br>
characters long.<br>
<br>
-- <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 rel=3D"nofollow noreferrer">std-proposal...@isocpp.org</a>.<br>
To post to this group, send email to <a rel=3D"nofollow noreferrer">std-pr.=
...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800=
-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" onclick=3D"this.href=
=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad2=
77-7800-53e2-35cc-16d11e1c65d9%40gmail.com&#39;;return true;" href=3D"https=
://groups.google.com/a/isocpp.org/d/msgid/std-proposals/095ad277-7800-53e2-=
35cc-16d11e1c65d9%40gmail.com" target=3D"_blank" rel=3D"nofollow">https://g=
roups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/095ad277-7800=
-53e2-<wbr>35cc-16d11e1c65d9%40gmail.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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 onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;" o=
nclick=3D"this.href=3D&#39;javascript:&#39;;return true;" href=3D"javascrip=
t:" target=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"FnahVpayBQA=
J">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a onmousedown=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;re=
turn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obf=
uscated-mailto=3D"FnahVpayBQAJ">std-pr...@isocpp.org</a>.<br>
To view this discussion on the web visit <a onmousedown=3D"this.href=3D&#39=
;https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803=
-43f2-8a13-8d725122627d%40isocpp.org?utm_medium\x3demail\x26utm_source\x3df=
ooter&#39;;return true;" onclick=3D"this.href=3D&#39;https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/305a7701-0803-43f2-8a13-8d725122627d=
%40isocpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;=
" href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/305a=
7701-0803-43f2-8a13-8d725122627d%40isocpp.org?utm_medium=3Demail&amp;utm_so=
urce=3Dfooter" target=3D"_blank" rel=3D"nofollow">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/305a7701-0803-43f2-<wbr>8a13-=
8d725122627d%40isocpp.org</a><wbr>.<br>
</blockquote></div></div></div>
</blockquote></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/23f11e4d-ed7d-4e12-8c92-3ec900edd692%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/23f11e4d-ed7d-4e12-8c92-3ec900edd692=
%40isocpp.org</a>.<br />

------=_Part_87420_325587996.1528633418020--

------=_Part_87419_1914685308.1528633418019--

.


Author: florian.csdt@gmail.com
Date: Sun, 10 Jun 2018 05:56:26 -0700 (PDT)
Raw View
------=_Part_54991_1705404419.1528635386493
Content-Type: multipart/alternative;
 boundary="----=_Part_54992_1844657316.1528635386493"

------=_Part_54992_1844657316.1528635386493
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9crit =
:
>
> Ok, now it is all clear.
>
> The problem is forward is used not only to pass along a forward reference=
,=20
> but also as to tool to trigger reference collapsing.=20
>
> Now the question is should a unified operator also being able to do that.=
=20
> I think the answer is YES - after all it is intended to be a drop-in=20
> replacement for both forward and move, no matter the use case.
>
>
> And I think it is actually simpler then initially thought.
>
>
> The heuristic is as follows - IFF an identifier is a lvalue reference -=
=20
> "move", in all other cases "forward".=20
> This might sound counterintuitive, but, given current language rules - it=
=20
> woks in all cases.
>
>
This doesn't work with "forwarding" references:
template <class T>
void foo(T&& t) { bar(t&&>); }

int i =3D 0;
foo(i); // foo<int&>(i) and decltype(t) -> int&
In this case, t within foo is an identifier whose type is an lvalue=20
reference, but where the correct behaviour is (most of the time) forward,=
=20
not move.
You don't want this l-value reference being transformed into a rvalue=20
reference.

But if the identifier is not a reference, then moving is the correct thing=
=20
to do. Actually, that's the current rule for std::forward:
decltype(x) | decltype(std::forward<decltype(x)>(x))
------------|---------------------------------------
T           | T&&
T&          | T&
T&&         | T&&

I really think that's a very sane default. When you really want T& -> T&&,=
=20
just call std::move that will work in any context you want this.
Here are some examples:
int i;
int &j;
int &&k;

i&&>; // i is     moved: decltype(i&&>) -> int&&
j&&>; // j is not moved: decltype(j&&>) -> int&
k&&>; // k is     moved: decltype(k&&>) -> int&&

std::move(i); // -> int&&
std::move(j); // -> int&&
std::move(k); // -> int&&
It doesn't matter if i, j or k are local variables, function parameters, or=
=20
even result of functions: the result is the same.

If you really want to move j in that case, I would say calling std::move(j)=
=20
explicitely is fine: this is clearly not used very often, but should still=
=20
be possible to do.

In short, use &&> when you want to give a variable/expression away.
And use std::move if you always want move. (no change required to std::move=
)
Those are very consistent rules that can be applied blindly, and don't=20
depend on the context (template code or regular code).
It only depends on the programmer intent. And that's what we want. (At=20
least, that's what I want)

--=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/229ff3c8-3ac9-4e5d-8f0c-9c32d91c0589%40isocpp.or=
g.

------=_Part_54992_1844657316.1528635386493
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn..=
..@gmail.com a =C3=A9crit=C2=A0:<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>Ok, now it is all clear.</div><div><br></div><div>Th=
e problem is forward is used not only to pass along a forward reference, bu=
t also as to tool to trigger reference collapsing.=C2=A0</div><div><br></di=
v><div>Now the question is should a unified operator also being able to do =
that. I think the answer is YES - after all it is intended to be a drop-in =
replacement for both forward and move, no matter the use case.</div><div><b=
r></div><div><br>And I think it is actually simpler then initially thought.=
</div><div><br></div><div><br></div><div>The heuristic is as follows - IFF =
an identifier is a lvalue reference - &quot;move&quot;, in all other cases =
&quot;forward&quot;. </div><div>This might sound counterintuitive, but, giv=
en current language rules - it woks in all cases.</div><div><br></div></div=
></blockquote><div><br></div><div>This doesn&#39;t work with &quot;forwardi=
ng&quot; references:<br></div><div><div style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">template</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> t</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ba=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">t</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;&gt;);</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"color=
: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">int</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"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">i</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: #800;" cl=
ass=3D"styled-by-prettify">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; =
int&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span></div></code></div>In this case, t within foo is an identifier who=
se type is an lvalue reference, but where the correct behaviour is (most of=
 the time) forward, not move.</div><div>You don&#39;t want this l-value ref=
erence being transformed into a rvalue reference.</div><div><br></div><div>=
But if the identifier is not a reference, then moving is the correct thing =
to do. Actually, that&#39;s the current rule for <span style=3D"font-family=
: courier new, monospace;">std::forward</span>:</div><div><span style=3D"fo=
nt-family: courier new, monospace;">decltype(x) | decltype(std::forward&lt;=
decltype(x)&gt;(x))</span></div><div><span style=3D"font-family: courier ne=
w, monospace;">------------|---------------------------------------<br></sp=
an></div><div><span style=3D"font-family: courier new, monospace;">T=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;&amp;</span>=
</div><div><span style=3D"font-family: courier new, monospace;">T&amp;=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 | T&amp;</span></div><d=
iv><span style=3D"font-family: courier new, monospace;">T&amp;&amp; =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 | T&amp;&amp;</span></div><div><br></div><div>I really=
 think that&#39;s a very sane default. When you really want T&amp; -&gt; T&=
amp;&amp;, just call <span style=3D"font-family: courier new, monospace;">s=
td::move</span> that will work in any context you want this.</div><div>Here=
 are some examples:</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"pret=
typrint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> i</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">j</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">k</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>i<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;&=
gt;;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// i is =C2=A0 =
=C2=A0 moved: decltype(i&amp;&amp;&gt;) -&gt; int&amp;&amp;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>j</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;&amp;&gt;;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">// j is not moved: decltype(j&amp;&=
amp;&gt;) -&gt; int&amp;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br>k</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&amp;&amp;&gt;;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// k is =C2=A0 =C2=A0 moved: decltype(k&amp;&amp;&gt;) -&gt; int&amp;&=
amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><b=
r>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">move</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">i</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: #800;" class=3D=
"styled-by-prettify">// -&gt; int&amp;&amp;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>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"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">j</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: #800;" class=3D"styled-by-prettify">// -&gt; int&amp;=
&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>s=
td</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><span style=3D=
"color: #000;" class=3D"styled-by-prettify">k</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// -&gt; int&amp;&amp;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span></div></code></div>It doesn&#39;t =
matter if <span style=3D"font-family: courier new, monospace;">i</span>, <s=
pan style=3D"font-family: courier new, monospace;">j</span> or <span style=
=3D"font-family: courier new, monospace;">k</span> are local variables, fun=
ction parameters, or even result of functions: the result is the same.</div=
><div><br></div><div>If you really want to move <span style=3D"font-family:=
 courier new, monospace;">j</span> in that case, I would say calling <span =
style=3D"font-family: courier new, monospace;">std::move(j)</span> explicit=
ely is fine: this is clearly not used very often, but should still be possi=
ble to do.</div><div><br></div><div>In short, use <span style=3D"font-famil=
y: courier new, monospace;">&amp;&amp;&gt;</span> when you want to give a v=
ariable/expression away.</div><div>And use <span style=3D"font-family: cour=
ier new, monospace;">std::move</span> if you always want move. (no change r=
equired to <span style=3D"font-family: courier new, monospace;">std::move</=
span>)</div><div>Those are very consistent rules that can be applied blindl=
y, and don&#39;t depend on the context (template code or regular code).</di=
v><div>It only depends on the programmer intent. And that&#39;s what we wan=
t. (At least, that&#39;s what I want)<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/229ff3c8-3ac9-4e5d-8f0c-9c32d91c0589%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/229ff3c8-3ac9-4e5d-8f0c-9c32d91c0589=
%40isocpp.org</a>.<br />

------=_Part_54992_1844657316.1528635386493--

------=_Part_54991_1705404419.1528635386493--

.


Author: mihailnajdenov@gmail.com
Date: Sun, 10 Jun 2018 07:33:58 -0700 (PDT)
Raw View
------=_Part_64930_174665546.1528641239056
Content-Type: multipart/alternative;
 boundary="----=_Part_64931_1966652305.1528641239057"

------=_Part_64931_1966652305.1528641239057
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>
>> Ok, now it is all clear.
>>
>> The problem is forward is used not only to pass along a forward=20
>> reference, but also as to tool to trigger reference collapsing.=20
>>
>> Now the question is should a unified operator also being able to do that=
..=20
>> I think the answer is YES - after all it is intended to be a drop-in=20
>> replacement for both forward and move, no matter the use case.
>>
>>
>> And I think it is actually simpler then initially thought.
>>
>>
>> The heuristic is as follows - IFF an identifier is a lvalue reference -=
=20
>> "move", in all other cases "forward".=20
>> This might sound counterintuitive, but, given current language rules - i=
t=20
>> woks in all cases.
>>
>>
> This doesn't work with "forwarding" references:
> template <class T>
> void foo(T&& t) { bar(t&&>); }
>
> int i =3D 0;
> foo(i); // foo<int&>(i) and decltype(t) -> int&
> In this case, t within foo is an identifier whose type is an lvalue=20
> reference, but where the correct behaviour is (most of the time) forward,=
=20
> not move.
> You don't want this l-value reference being transformed into a rvalue=20
> reference.
>


By lvalue reference I meant real lvalue reference NOT the result of=20
collapsing!=20

In a forwarding ref case the compiler will always use 'give' (as was in the=
=20
example!), *not matter what the forwarding reference collapses to!*

The compiler will only EVER use 'giveref' to cast a real lvalue (T&& is not=
=20
an lvalue anyway)

I believe this will work *all the time*, given current prerequisites - to=
=20
be *as-if* move or forward is used correctly.=20

=20

>
> But if the identifier is not a reference, then moving is the correct thin=
g=20
> to do. Actually, that's the current rule for std::forward:
> ...
> It doesn't matter if i, j or k are local variables, function parameters,=
=20
> or even result of functions: the result is the same.
>
> If you really want to move j in that case, I would say calling=20
> std::move(j) explicitely is fine: this is clearly not used very often,=20
> but should still be possible to do.
>
> In short, use &&> when you want to give a variable/expression away.
> And use std::move if you always want move. (no change required to=20
> std::move)
> Those are very consistent rules that can be applied blindly, and don't=20
> depend on the context (template code or regular code).
> It only depends on the programmer intent. And that's what we want. (At=20
> least, that's what I want)
>


If we have to use both &&> and move, we are back to where we stared - learn=
=20
when to use what. forward vs move is now &&> vs move=20

All we changed are the default. Yes the new defaults are nice, safe, but I=
=20
want *one* keyword/operator, that *Just Works* (TM), so the user will no=20
longer need to learn anything, expect "this is how give objects".

All the nuances are gone for good.=20

"This is how you give objects".=20
"Given object are not to be used."

This is all a user needs to know to use objects correctly.

An intermediate user will learn that
"If the object you have given was yours (local copy) or was a reference to=
=20
one that was about to die (concrete_type&&) you can reuse its name to place=
=20
a different object."
"Given objects are moved if they can and copied if they can not."=20

That's it. No new rules just streamline of the already established=20
practice!=20

=20

--=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/15f4d696-a395-4834-8e95-cf479d1746cf%40isocpp.or=
g.

------=_Part_64931_1966652305.1528641239057
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, flor=
ia...@gmail.com 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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>Ok, now it is all clear.</div><div><br></div><div>The prob=
lem is forward is used not only to pass along a forward reference, but also=
 as to tool to trigger reference collapsing.=C2=A0</div><div><br></div><div=
>Now the question is should a unified operator also being able to do that. =
I think the answer is YES - after all it is intended to be a drop-in replac=
ement for both forward and move, no matter the use case.</div><div><br></di=
v><div><br>And I think it is actually simpler then initially thought.</div>=
<div><br></div><div><br></div><div>The heuristic is as follows - IFF an ide=
ntifier is a lvalue reference - &quot;move&quot;, in all other cases &quot;=
forward&quot;. </div><div>This might sound counterintuitive, but, given cur=
rent language rules - it woks in all cases.</div><div><br></div></div></blo=
ckquote><div><br></div><div>This doesn&#39;t work with &quot;forwarding&quo=
t; references:<br></div><div><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">template</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cla=
ss</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">vo=
id</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&=
amp;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#000">t</span><span style=3D"color:#660">&amp;&amp;&gt=
;);</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">i=
nt</span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#000">i</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#800">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; int=
&amp;</span><span style=3D"color:#000"><br></span></div></code></div>In thi=
s case, t within foo is an identifier whose type is an lvalue reference, bu=
t where the correct behaviour is (most of the time) forward, not move.</div=
><div>You don&#39;t want this l-value reference being transformed into a rv=
alue reference.</div></div></blockquote><div><br></div><div><br></div><div>=
By <span style=3D"display: inline !important; float: none; background-color=
: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot=
;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-ali=
gn: left; text-decoration: none; text-indent: 0px; text-transform: none; -w=
ebkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">lval=
ue reference I meant real=C2=A0<span style=3D"display: inline !important; f=
loat: none; background-color: transparent; color: rgb(34, 34, 34); font-fam=
ily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">lvalue reference NOT the result of collapsing!=C2=
=A0</span></span></div><div><span style=3D"display: inline !important; floa=
t: none; background-color: transparent; color: rgb(34, 34, 34); font-family=
: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font=
-style: normal; font-variant: normal; font-weight: 400; letter-spacing: nor=
mal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px;=
 text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal;=
 word-spacing: 0px;"><span style=3D"display: inline !important; float: none=
; background-color: transparent; color: rgb(34, 34, 34); font-family: &quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style:=
 normal; font-variant: normal; font-weight: 400; letter-spacing: normal; or=
phans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;"><br></span></span></div><div><span style=3D"display: inline !=
important; float: none; background-color: transparent; color: rgb(34, 34, 3=
4); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; orphans: 2; text-align: left; text-decoration: none; te=
xt-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white=
-space: normal; word-spacing: 0px;"><span style=3D"display: inline !importa=
nt; float: none; background-color: transparent; color: rgb(34, 34, 34); fon=
t-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13=
px; font-style: normal; font-variant: normal; font-weight: 400; letter-spac=
ing: normal; orphans: 2; text-align: left; text-decoration: none; text-inde=
nt: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space:=
 normal; word-spacing: 0px;">In a forwarding ref case the compiler will alw=
ays use &#39;give&#39; (as was in the example!), <i>not matter what the for=
warding reference collapses to!</i></span></span></div><div><span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"display=
: inline !important; float: none; background-color: transparent; color: rgb=
(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;"><i></i><i></i><i></i><br></sp=
an></span></div><div><span style=3D"display: inline !important; float: none=
; background-color: transparent; color: rgb(34, 34, 34); font-family: &quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style:=
 normal; font-variant: normal; font-weight: 400; letter-spacing: normal; or=
phans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-t=
ransform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-s=
pacing: 0px;"><span style=3D"display: inline !important; float: none; backg=
round-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal=
; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: =
2; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
 0px;">The compiler will only EVER use &#39;giveref&#39; to cast a real lva=
lue (T&amp;&amp; is not an lvalue anyway)</span></span></div><div><span sty=
le=3D"display: inline !important; float: none; background-color: transparen=
t; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal;=
 font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; te=
xt-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-s=
troke-width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"d=
isplay: inline !important; float: none; background-color: transparent; colo=
r: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif; font-size: 13px; font-style: normal; font-variant: normal; font-w=
eight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-deco=
ration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-w=
idth: 0px; white-space: normal; word-spacing: 0px;"><br></span></span></div=
><div><span style=3D"display: inline !important; float: none; background-co=
lor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
 -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">I believ=
e this will work <i>all the time</i>, given current prerequisites - to be <=
i>as-if</i> move or forward is used correctly.=C2=A0</span></span></div><di=
v><span style=3D"display: inline !important; float: none; background-color:=
 transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varia=
nt: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span=
 style=3D"display: inline !important; float: none; background-color: transp=
arent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span><=
/span></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div><br></div><div>But if the identifier is not a referenc=
e, then moving is the correct thing to do. Actually, that&#39;s the current=
 rule for <span style=3D"font-family:courier new,monospace">std::forward</s=
pan>:</div><div><span style=3D"font-family:courier new,monospace">...</span=
><code><span style=3D"color:#000"><br></span></code></div><div>It doesn&#39=
;t matter if <span style=3D"font-family:courier new,monospace">i</span>, <s=
pan style=3D"font-family:courier new,monospace">j</span> or <span style=3D"=
font-family:courier new,monospace">k</span> are local variables, function p=
arameters, or even result of functions: the result is the same.</div><div><=
br></div><div>If you really want to move <span style=3D"font-family:courier=
 new,monospace">j</span> in that case, I would say calling <span style=3D"f=
ont-family:courier new,monospace">std::move(j)</span> explicitely is fine: =
this is clearly not used very often, but should still be possible to do.</d=
iv><div><br></div><div>In short, use <span style=3D"font-family:courier new=
,monospace">&amp;&amp;&gt;</span> when you want to give a variable/expressi=
on away.</div><div>And use <span style=3D"font-family:courier new,monospace=
">std::move</span> if you always want move. (no change required to <span st=
yle=3D"font-family:courier new,monospace">std::move</span>)</div><div>Those=
 are very consistent rules that can be applied blindly, and don&#39;t depen=
d on the context (template code or regular code).</div><div>It only depends=
 on the programmer intent. And that&#39;s what we want. (At least, that&#39=
;s what I want)<br></div></div></blockquote><div><br></div><div><br></div><=
div>If we have to use both &amp;&amp;&gt; and move, we are back to where we=
 stared - learn when to use what. forward vs move is now &amp;&amp;&gt; vs =
move=C2=A0</div><div><br></div><div>All we changed are the default. Yes the=
 new defaults are nice, safe, but I want <i>one</i>=C2=A0<span style=3D"dis=
play: inline !important; float: none; background-color: transparent; color:=
 rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif; font-size: 13px; font-style: normal; font-variant: normal; font-wei=
ght: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decora=
tion: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wid=
th: 0px; white-space: normal; word-spacing: 0px;">keyword/operator, that <b=
>Just Works</b> (TM), so the user will no longer need to learn anything, ex=
pect &quot;this is how give objects&quot;.</span></div><div><span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div>=
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">All the=
 nuances are gone for good.=C2=A0</span></div><div><span style=3D"display: =
inline !important; float: none; background-color: transparent; color: rgb(3=
4, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: =
none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0p=
x; white-space: normal; word-spacing: 0px;"><br></span></div><div><span sty=
le=3D"display: inline !important; float: none; background-color: transparen=
t; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal;=
 font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; te=
xt-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-s=
troke-width: 0px; white-space: normal; word-spacing: 0px;">&quot;This is ho=
w you give objects&quot;.=C2=A0</span><br></div><div><span style=3D"display=
: inline !important; float: none; background-color: transparent; color: rgb=
(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;">&quot;Given object are not to=
 be used.&quot;</span></div><div><span style=3D"display: inline !important;=
 float: none; background-color: transparent; color: rgb(34, 34, 34); font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; orphans: 2; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;"><br></span></div><div><span style=3D"text-align: =
left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; lette=
r-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif; font-size: 13px; font-variant: normal; word-spacing: 0px; display:=
 inline !important; white-space: normal; orphans: 2; float: none; -webkit-t=
ext-stroke-width: 0px; background-color: transparent;"><span style=3D"displ=
ay: inline !important; float: none; background-color: transparent; color: r=
gb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-s=
erif; font-size: 13px; font-style: normal; font-variant: normal; font-weigh=
t: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decorati=
on: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width=
: 0px; white-space: normal; word-spacing: 0px;">This is all a user needs to=
 know to use objects correctly.</span></span><br></div><div><span style=3D"=
display: inline !important; float: none; background-color: transparent; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-dec=
oration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-=
width: 0px; white-space: normal; word-spacing: 0px;"><br></span></div><div>=
<span style=3D"display: inline !important; float: none; background-color: t=
ransparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant=
: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align:=
 left; text-decoration: none; text-indent: 0px; text-transform: none; -webk=
it-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">An inte=
rmediate user will learn that</span></div><div><span style=3D"display: inli=
ne !important; float: none; background-color: transparent; color: rgb(34, 3=
4, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; fo=
nt-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; =
letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none=
; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; w=
hite-space: normal; word-spacing: 0px;">&quot;If the object you have given =
was yours (local copy) or was a reference to one that was about to die (con=
crete_type&amp;&amp;) you can reuse its name to place a different object.&q=
uot;</span></div><div><span style=3D"text-align: left; color: rgb(34, 34, 3=
4); text-transform: none; text-indent: 0px; letter-spacing: normal; font-fa=
mily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; =
font-variant: normal; word-spacing: 0px; display: inline !important; white-=
space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; bac=
kground-color: transparent;"><span style=3D"background-color: transparent; =
border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bot=
tom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; borde=
r-image-slice: 100%; border-image-source: none; border-image-width: 1; bord=
er-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width:=
 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; border=
-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: non=
e; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: n=
one; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,s=
ans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-=
weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; =
margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-d=
ecoration: none; text-indent: 0px; text-transform: none; -webkit-text-strok=
e-width: 0px; white-space: normal; word-spacing: 0px;"><span style=3D"backg=
round-color: transparent; border-bottom-color: rgb(34, 34, 34); border-bott=
om-style: none; border-bottom-width: 0px; border-image-outset: 0; border-im=
age-repeat: stretch; border-image-slice: 100%; border-image-source: none; b=
order-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style=
: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border=
-right-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, =
34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34);=
 display: inline; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;=
quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; f=
ont-variant: normal; font-weight: 400; letter-spacing: normal; margin-botto=
m: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; p=
adding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;">&quot;<span style=3D"display: inline !important; float: none; backgro=
und-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2;=
 text-align: left; text-decoration: none; text-indent: 0px; text-transform:=
 none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0=
px;">Given objects</span> are moved if they can and copied if they can not.=
&quot;=C2=A0</span></span><b></b><i></i><u></u><sub></sub><sup></sup><strik=
e></strike><br></span></div><div><span style=3D"display: inline !important;=
 float: none; background-color: transparent; color: rgb(34, 34, 34); font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; orphans: 2; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;"><b></b><i></i><u></u><sub></sub><sup></sup><strik=
e></strike><br></span></div><div><span style=3D"display: inline !important;=
 float: none; background-color: transparent; color: rgb(34, 34, 34); font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; orphans: 2; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;">That&#39;s it. No new rules just streamline of th=
e already established practice!=C2=A0</span></div><div><br></div><div></div=
><div>=C2=A0</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/15f4d696-a395-4834-8e95-cf479d1746cf%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/15f4d696-a395-4834-8e95-cf479d1746cf=
%40isocpp.org</a>.<br />

------=_Part_64931_1966652305.1528641239057--

------=_Part_64930_174665546.1528641239056--

.


Author: inkwizytoryankes@gmail.com
Date: Sun, 10 Jun 2018 07:58:28 -0700 (PDT)
Raw View
------=_Part_47218_1241976613.1528642708101
Content-Type: multipart/alternative;
 boundary="----=_Part_47219_1326534567.1528642708102"

------=_Part_47219_1326534567.1528642708102
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 4:33:59 PM UTC+2, mihailn...@gmail.com wrote:
>
>
>
> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>> Ok, now it is all clear.
>>>
>>> The problem is forward is used not only to pass along a forward=20
>>> reference, but also as to tool to trigger reference collapsing.=20
>>>
>>> Now the question is should a unified operator also being able to do=20
>>> that. I think the answer is YES - after all it is intended to be a drop=
-in=20
>>> replacement for both forward and move, no matter the use case.
>>>
>>>
>>> And I think it is actually simpler then initially thought.
>>>
>>>
>>> The heuristic is as follows - IFF an identifier is a lvalue reference -=
=20
>>> "move", in all other cases "forward".=20
>>> This might sound counterintuitive, but, given current language rules -=
=20
>>> it woks in all cases.
>>>
>>>
>> This doesn't work with "forwarding" references:
>> template <class T>
>> void foo(T&& t) { bar(t&&>); }
>>
>> int i =3D 0;
>> foo(i); // foo<int&>(i) and decltype(t) -> int&
>> In this case, t within foo is an identifier whose type is an lvalue=20
>> reference, but where the correct behaviour is (most of the time) forward=
,=20
>> not move.
>> You don't want this l-value reference being transformed into a rvalue=20
>> reference.
>>
>
>
> By lvalue reference I meant real lvalue reference NOT the result of=20
> collapsing!=20
>
> In a forwarding ref case the compiler will always use 'give' (as was in=
=20
> the example!), *not matter what the forwarding reference collapses to!*
>
> The compiler will only EVER use 'giveref' to cast a real lvalue (T&& is=
=20
> not an lvalue anyway)
>
> I believe this will work *all the time*, given current prerequisites - to=
=20
> be *as-if* move or forward is used correctly.=20
>
> =20
>
>>
>> But if the identifier is not a reference, then moving is the correct=20
>> thing to do. Actually, that's the current rule for std::forward:
>> ...
>> It doesn't matter if i, j or k are local variables, function parameters,=
=20
>> or even result of functions: the result is the same.
>>
>> If you really want to move j in that case, I would say calling=20
>> std::move(j) explicitely is fine: this is clearly not used very often,=
=20
>> but should still be possible to do.
>>
>> In short, use &&> when you want to give a variable/expression away.
>> And use std::move if you always want move. (no change required to=20
>> std::move)
>> Those are very consistent rules that can be applied blindly, and don't=
=20
>> depend on the context (template code or regular code).
>> It only depends on the programmer intent. And that's what we want. (At=
=20
>> least, that's what I want)
>>
>
>
> If we have to use both &&> and move, we are back to where we stared -=20
> learn when to use what. forward vs move is now &&> vs move=20
>
> All we changed are the default. Yes the new defaults are nice, safe, but =
I=20
> want *one* keyword/operator, that *Just Works* (TM), so the user will no=
=20
> longer need to learn anything, expect "this is how give objects".
>
> All the nuances are gone for good.=20
>
> "This is how you give objects".=20
> "Given object are not to be used."
>
> This is all a user needs to know to use objects correctly.
>
> An intermediate user will learn that
> "If the object you have given was yours (local copy) or was a reference t=
o=20
> one that was about to die (concrete_type&&) you can reuse its name to pla=
ce=20
> a different object."
> "Given objects are moved if they can and copied if they can not."=20
>
> That's it. No new rules just streamline of the already established=20
> practice!=20
>
> =20
>

I think instead of `x&&>`  would better to use keyword `forward_cast(x)`,=
=20
it lot longer but usually you will need type only `forw` to allow for code=
=20
completion to know that you want type.
Another benefit is name is more descriptive that some, easier to search=20
(`&&>` is current allowed in templates: `A<T&&>`).

--=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/8debddce-3302-4466-b97c-babb39b62efc%40isocpp.or=
g.

------=_Part_47219_1326534567.1528642708102
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 4:33:59 PM UTC+2, miha=
iln...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria..=
..@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.co=
m</a> a =C3=A9crit=C2=A0:<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>Ok, now it is all clear.</div><div><br></div><div>The problem=
 is forward is used not only to pass along a forward reference, but also as=
 to tool to trigger reference collapsing.=C2=A0</div><div><br></div><div>No=
w the question is should a unified operator also being able to do that. I t=
hink the answer is YES - after all it is intended to be a drop-in replaceme=
nt for both forward and move, no matter the use case.</div><div><br></div><=
div><br>And I think it is actually simpler then initially thought.</div><di=
v><br></div><div><br></div><div>The heuristic is as follows - IFF an identi=
fier is a lvalue reference - &quot;move&quot;, in all other cases &quot;for=
ward&quot;. </div><div>This might sound counterintuitive, but, given curren=
t language rules - it woks in all cases.</div><div><br></div></div></blockq=
uote><div><br></div><div>This doesn&#39;t work with &quot;forwarding&quot; =
references:<br></div><div><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class<=
/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:#660">(</s=
pan><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&amp=
;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><=
span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">t</span><span style=3D"color:#660">&amp;&amp;&gt;);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">int<=
/span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span>=
<span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000">i</span><spa=
n style=3D"color:#660">);</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#800">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; int&amp;=
</span><span style=3D"color:#000"><br></span></div></code></div>In this cas=
e, t within foo is an identifier whose type is an lvalue reference, but whe=
re the correct behaviour is (most of the time) forward, not move.</div><div=
>You don&#39;t want this l-value reference being transformed into a rvalue =
reference.</div></div></blockquote><div><br></div><div><br></div><div>By <s=
pan style=3D"display:inline!important;float:none;background-color:transpare=
nt;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,=
sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight=
:400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px">lvalue refere=
nce I meant real=C2=A0<span style=3D"display:inline!important;float:none;ba=
ckground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-va=
riant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-dec=
oration:none;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px">lvalue reference NOT the result of collapsing!=C2=A0</span></spa=
n></div><div><span style=3D"display:inline!important;float:none;background-=
color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;H=
elvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:nor=
mal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:n=
one;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px=
"><span style=3D"display:inline!important;float:none;background-color:trans=
parent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-we=
ight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-in=
dent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></spa=
n></span></div><div><span style=3D"display:inline!important;float:none;back=
ground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,=
&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-vari=
ant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decor=
ation:none;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px"><span style=3D"display:inline!important;float:none;background-colo=
r:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helve=
tica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;=
font-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;=
text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">In=
 a forwarding ref case the compiler will always use &#39;give&#39; (as was =
in the example!), <i>not matter what the forwarding reference collapses to!=
</i></span></span></div><div><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><span style=3D"display:inline!important;float:none;backgr=
ound-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varian=
t:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorat=
ion:none;text-indent:0px;text-transform:none;white-space:normal;word-spacin=
g:0px"><i></i><i></i><i></i><br></span></span></div><div><span style=3D"dis=
play:inline!important;float:none;background-color:transparent;color:rgb(34,=
34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-=
size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spac=
ing:normal;text-align:left;text-decoration:none;text-indent:0px;text-transf=
orm:none;white-space:normal;word-spacing:0px"><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">The compiler will only EVER use &#39;giv=
eref&#39; to cast a real lvalue (T&amp;&amp; is not an lvalue anyway)</span=
></span></div><div><span style=3D"display:inline!important;float:none;backg=
round-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varia=
nt:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decora=
tion:none;text-indent:0px;text-transform:none;white-space:normal;word-spaci=
ng:0px"><span style=3D"display:inline!important;float:none;background-color=
:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;f=
ont-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;t=
ext-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br=
></span></span></div><div><span style=3D"display:inline!important;float:non=
e;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fon=
t-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text=
-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wor=
d-spacing:0px"><span style=3D"display:inline!important;float:none;backgroun=
d-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot=
;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:n=
ormal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration=
:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0=
px">I believe this will work <i>all the time</i>, given current prerequisit=
es - to be <i>as-if</i> move or forward is used correctly.=C2=A0</span></sp=
an></div><div><span style=3D"display:inline!important;float:none;background=
-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:no=
rmal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:=
none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x"><span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-w=
eight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></sp=
an></span></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"><d=
iv dir=3D"ltr"><div><br></div><div>But if the identifier is not a reference=
, then moving is the correct thing to do. Actually, that&#39;s the current =
rule for <span style=3D"font-family:courier new,monospace">std::forward</sp=
an>:</div><div><span style=3D"font-family:courier new,monospace">...</span>=
<code><span style=3D"color:#000"><br></span></code></div><div>It doesn&#39;=
t matter if <span style=3D"font-family:courier new,monospace">i</span>, <sp=
an style=3D"font-family:courier new,monospace">j</span> or <span style=3D"f=
ont-family:courier new,monospace">k</span> are local variables, function pa=
rameters, or even result of functions: the result is the same.</div><div><b=
r></div><div>If you really want to move <span style=3D"font-family:courier =
new,monospace">j</span> in that case, I would say calling <span style=3D"fo=
nt-family:courier new,monospace">std::move(j)</span> explicitely is fine: t=
his is clearly not used very often, but should still be possible to do.</di=
v><div><br></div><div>In short, use <span style=3D"font-family:courier new,=
monospace">&amp;&amp;&gt;</span> when you want to give a variable/expressio=
n away.</div><div>And use <span style=3D"font-family:courier new,monospace"=
>std::move</span> if you always want move. (no change required to <span sty=
le=3D"font-family:courier new,monospace">std::move</span>)</div><div>Those =
are very consistent rules that can be applied blindly, and don&#39;t depend=
 on the context (template code or regular code).</div><div>It only depends =
on the programmer intent. And that&#39;s what we want. (At least, that&#39;=
s what I want)<br></div></div></blockquote><div><br></div><div><br></div><d=
iv>If we have to use both &amp;&amp;&gt; and move, we are back to where we =
stared - learn when to use what. forward vs move is now &amp;&amp;&gt; vs m=
ove=C2=A0</div><div><br></div><div>All we changed are the default. Yes the =
new defaults are nice, safe, but I want <i>one</i>=C2=A0<span style=3D"disp=
lay:inline!important;float:none;background-color:transparent;color:rgb(34,3=
4,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-s=
ize:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spaci=
ng:normal;text-align:left;text-decoration:none;text-indent:0px;text-transfo=
rm:none;white-space:normal;word-spacing:0px">keyword/operator, that <b>Just=
 Works</b> (TM), so the user will no longer need to learn anything, expect =
&quot;this is how give objects&quot;.</span></div><div><span style=3D"displ=
ay:inline!important;float:none;background-color:transparent;color:rgb(34,34=
,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-si=
ze:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacin=
g:normal;text-align:left;text-decoration:none;text-indent:0px;text-transfor=
m:none;white-space:normal;word-spacing:0px"><br></span></div><div><span sty=
le=3D"display:inline!important;float:none;background-color:transparent;colo=
r:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-se=
rif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;le=
tter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;te=
xt-transform:none;white-space:normal;word-spacing:0px">All the nuances are =
gone for good.=C2=A0</span></div><div><span style=3D"display:inline!importa=
nt;float:none;background-color:transparent;color:rgb(34,34,34);font-family:=
&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-styl=
e:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:left;text-decoration:none;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px"><br></span></div><div><span style=3D"display:inl=
ine!important;float:none;background-color:transparent;color:rgb(34,34,34);f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:norm=
al;text-align:left;text-decoration:none;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px">&quot;This is how you give objects&qu=
ot;.=C2=A0</span><br></div><div><span style=3D"display:inline!important;flo=
at:none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;=
Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norm=
al;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:lef=
t;text-decoration:none;text-indent:0px;text-transform:none;white-space:norm=
al;word-spacing:0px">&quot;Given object are not to be used.&quot;</span></d=
iv><div><span style=3D"display:inline!important;float:none;background-color=
:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;f=
ont-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;t=
ext-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br=
></span></div><div><span style=3D"text-align:left;color:rgb(34,34,34);text-=
transform:none;text-indent:0px;letter-spacing:normal;font-family:&quot;Aria=
l&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-variant:normal=
;word-spacing:0px;display:inline!important;white-space:normal;float:none;ba=
ckground-color:transparent"><span style=3D"display:inline!important;float:n=
one;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Aria=
l&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;f=
ont-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;te=
xt-decoration:none;text-indent:0px;text-transform:none;white-space:normal;w=
ord-spacing:0px">This is all a user needs to know to use objects correctly.=
</span></span><br></div><div><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><br></span></div><div><span style=3D"display:inline!impor=
tant;float:none;background-color:transparent;color:rgb(34,34,34);font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-a=
lign:left;text-decoration:none;text-indent:0px;text-transform:none;white-sp=
ace:normal;word-spacing:0px">An intermediate user will learn that</span></d=
iv><div><span style=3D"display:inline!important;float:none;background-color=
:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;f=
ont-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;t=
ext-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">&qu=
ot;If the object you have given was yours (local copy) or was a reference t=
o one that was about to die (concrete_type&amp;&amp;) you can reuse its nam=
e to place a different object.&quot;</span></div><div><span style=3D"text-a=
lign:left;color:rgb(34,34,34);text-transform:none;text-indent:0px;letter-sp=
acing:normal;font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif=
;font-size:13px;font-variant:normal;word-spacing:0px;display:inline!importa=
nt;white-space:normal;float:none;background-color:transparent"><span><span>=
&quot;<span style=3D"display:inline!important;float:none;background-color:t=
ransparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fon=
t-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Given=
 objects</span> are moved if they can and copied if they can not.&quot;=C2=
=A0</span></span><b></b><i></i><u></u><sub></sub><sup></sup><strike></strik=
e><br></span></div><div><span style=3D"display:inline!important;float:none;=
background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-=
variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-d=
ecoration:none;text-indent:0px;text-transform:none;white-space:normal;word-=
spacing:0px"><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><b=
r></span></div><div><span style=3D"display:inline!important;float:none;back=
ground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,=
&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-vari=
ant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decor=
ation:none;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px">That&#39;s it. No new rules just streamline of the already establi=
shed practice!=C2=A0</span></div><div><br></div><div></div><div>=C2=A0</div=
></div></blockquote><div><br></div><div>I think instead of `x&amp;&amp;&gt;=
`=C2=A0 would better to use keyword `forward_cast(x)`, it lot longer but us=
ually you will need type only `forw` to allow for code completion to know t=
hat you want type.</div><div>Another benefit is name is more descriptive th=
at some, easier to search (`&amp;&amp;&gt;` is current allowed in templates=
: `A&lt;T&amp;&amp;&gt;`).<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/8debddce-3302-4466-b97c-babb39b62efc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8debddce-3302-4466-b97c-babb39b62efc=
%40isocpp.org</a>.<br />

------=_Part_47219_1326534567.1528642708102--

------=_Part_47218_1241976613.1528642708101--

.


Author: florian.csdt@gmail.com
Date: Sun, 10 Jun 2018 08:09:36 -0700 (PDT)
Raw View
------=_Part_87799_787017934.1528643376737
Content-Type: multipart/alternative;
 boundary="----=_Part_87800_2066597840.1528643376738"

------=_Part_87800_2066597840.1528643376738
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9crit =
:
>
>
>
> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>> Ok, now it is all clear.
>>>
>>> The problem is forward is used not only to pass along a forward=20
>>> reference, but also as to tool to trigger reference collapsing.=20
>>>
>>> Now the question is should a unified operator also being able to do=20
>>> that. I think the answer is YES - after all it is intended to be a drop=
-in=20
>>> replacement for both forward and move, no matter the use case.
>>>
>>>
>>> And I think it is actually simpler then initially thought.
>>>
>>>
>>> The heuristic is as follows - IFF an identifier is a lvalue reference -=
=20
>>> "move", in all other cases "forward".=20
>>> This might sound counterintuitive, but, given current language rules -=
=20
>>> it woks in all cases.
>>>
>>>
>> This doesn't work with "forwarding" references:
>> template <class T>
>> void foo(T&& t) { bar(t&&>); }
>>
>> int i =3D 0;
>> foo(i); // foo<int&>(i) and decltype(t) -> int&
>> In this case, t within foo is an identifier whose type is an lvalue=20
>> reference, but where the correct behaviour is (most of the time) forward=
,=20
>> not move.
>> You don't want this l-value reference being transformed into a rvalue=20
>> reference.
>>
>
>
> By lvalue reference I meant real lvalue reference NOT the result of=20
> collapsing!=20
>

But you can always imagine some meta-function that give the same result as=
=20
reference collapsing without relying on reference collapsing, and that=20
being used as a function parameter.
Reference collapsing is a bit like "forwarding" reference: once it has=20
happened, it should behave the same as if never happened in the first place=
=20
if the types are equals.

template <class T> struct collapse      { using type =3D T&&; };
template <class T> struct collapse<T& > { using type =3D T& ; };
template <class T> struct collapse<T&&> { using type =3D T&&; };
template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
Optimization for trivial types=20
template <class T> using  collapse_t =3D typename collapse<T>::type;


template <class T>
struct Helper {
  void operator()(collapse_t<T> t) {
    bar(std::forward<T>(t)); // What do you do here?
};

template <class T>
void foo(T&& t) {
  Helper<T>{}(std::forward<T>(t));
}
=20
In this example, you have no actual reference collapsing. And you cannot=20
implement it with reference collapsing only, as you need the specialization=
=20
for pointers.
This is the kind of code I'm worried about with your operator.
And it should work the same if, for whatever reason I change it back to=20
some simpler implementation using reference collapsing.
Reference collapsing is transparent!


> In a forwarding ref case the compiler will always use 'give' (as was in=
=20
> the example!), *not matter what the forwarding reference collapses to!*
>

> The compiler will only EVER use 'giveref' to cast a real lvalue (T&& is=
=20
> not an lvalue anyway)
>

T&& might be an lvalue reference.
=20

>
> I believe this will work *all the time*, given current prerequisites - to=
=20
> be *as-if* move or forward is used correctly.=20
>
>
See my example above.
=20

> =20
>
>>
>> But if the identifier is not a reference, then moving is the correct=20
>> thing to do. Actually, that's the current rule for std::forward:
>> ...
>> It doesn't matter if i, j or k are local variables, function parameters,=
=20
>> or even result of functions: the result is the same.
>>
>> If you really want to move j in that case, I would say calling=20
>> std::move(j) explicitely is fine: this is clearly not used very often,=
=20
>> but should still be possible to do.
>>
>> In short, use &&> when you want to give a variable/expression away.
>> And use std::move if you always want move. (no change required to=20
>> std::move)
>> Those are very consistent rules that can be applied blindly, and don't=
=20
>> depend on the context (template code or regular code).
>> It only depends on the programmer intent. And that's what we want. (At=
=20
>> least, that's what I want)
>>
>
>
> If we have to use both &&> and move, we are back to where we stared -=20
> learn when to use what. forward vs move is now &&> vs move=20
>

This is not the same. &&> and std::move are not for the same purpose:
&&>: I don't use this object anymore.
std::move(): nobody uses this object anymore (I promise), so the callee can=
=20
do anything they want with it.

It appears that, when you own the object (either local variable, or rvalue=
=20
reference), the two are the same, but that's it!
My feeling is, your operator will be used most of the time, even where=20
std::move is currently used. And *very* rarely, std::move will be required,=
=20
like to implement std::swap.
=20

>
> All we changed are the default. Yes the new defaults are nice, safe, but =
I=20
> want *one* keyword/operator, that *Just Works* (TM), so the user will no=
=20
> longer need to learn anything, expect "this is how give objects".
>
> All the nuances are gone for good.=20
>

But you will have some cases where it won't work (see my example).
=20

>
> "This is how you give objects".=20
> "Given object are not to be used."
>

"This is how you tell you don't need objects anymore"

std::move is not for that. In a way, std::move will be to &&> what=20
const_cast is to static_cast.

=20

>
> This is all a user needs to know to use objects correctly.
>
> An intermediate user will learn that
> "If the object you have given was yours (local copy) or was a reference t=
o=20
> one that was about to die (concrete_type&&) you can reuse its name to pla=
ce=20
> a different object."
> "Given objects are moved if they can and copied if they can not."=20
>

I completely agree with those. That's why I think &&> should not move=20
lvalue references: you don't own them.
=20

>
> That's it. No new rules just streamline of the already established=20
> practice!=20
>
> =20
>
It's better to have "user rules" that give consitent behaviours, than "no=
=20
user rules" giving inconsistent results depending where it is used.
=20

--=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/b685630b-f20d-4a07-b85e-fce4c287525d%40isocpp.or=
g.

------=_Part_87800_2066597840.1528643376738
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn..=
..@gmail.com a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>=
floria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@=
gmail.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>Ok, now it is all clear.</div><div><br></div><div>The p=
roblem is forward is used not only to pass along a forward reference, but a=
lso as to tool to trigger reference collapsing.=C2=A0</div><div><br></div><=
div>Now the question is should a unified operator also being able to do tha=
t. I think the answer is YES - after all it is intended to be a drop-in rep=
lacement for both forward and move, no matter the use case.</div><div><br><=
/div><div><br>And I think it is actually simpler then initially thought.</d=
iv><div><br></div><div><br></div><div>The heuristic is as follows - IFF an =
identifier is a lvalue reference - &quot;move&quot;, in all other cases &qu=
ot;forward&quot;. </div><div>This might sound counterintuitive, but, given =
current language rules - it woks in all cases.</div><div><br></div></div></=
blockquote><div><br></div><div>This doesn&#39;t work with &quot;forwarding&=
quot; references:<br></div><div><div style=3D"background-color:rgb(250,250,=
250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><co=
de><div><span style=3D"color:#008">template</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
class</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:#660=
">(</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&am=
p;&amp;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660=
">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</=
span><span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#000">t</span><span style=3D"color:#660">&amp;&amp;=
&gt;);</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
}</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">int</span><span style=3D"color:#000"> i </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo=
</span><span style=3D"color:#660">(</span><span style=3D"color:#000">i</spa=
n><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#800">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; in=
t&amp;</span><span style=3D"color:#000"><br></span></div></code></div>In th=
is case, t within foo is an identifier whose type is an lvalue reference, b=
ut where the correct behaviour is (most of the time) forward, not move.</di=
v><div>You don&#39;t want this l-value reference being transformed into a r=
value reference.</div></div></blockquote><div><br></div><div><br></div><div=
>By <span style=3D"display:inline!important;float:none;background-color:tra=
nsparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-=
weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px">lvalue =
reference I meant real=C2=A0<span style=3D"display:inline!important;float:n=
one;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Aria=
l&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;f=
ont-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;te=
xt-decoration:none;text-indent:0px;text-transform:none;white-space:normal;w=
ord-spacing:0px">lvalue reference NOT the result of collapsing!=C2=A0</span=
></span></div></div></blockquote><div><br></div><div>But you can always ima=
gine some meta-function that give the same result as reference collapsing w=
ithout relying on reference collapsing, and that being used as a function p=
arameter.</div><div>Reference collapsing is a bit like &quot;forwarding&quo=
t; reference: once it has happened, it should behave the same as if never h=
appened in the first place if the types are equals.</div><div><br></div><di=
v><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187=
, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-w=
ord;" class=3D"prettyprint"><code class=3D"prettyprint"><div><span style=3D=
"color: #008;" class=3D"styled-by-prettify">template</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> co=
llapse =C2=A0 =C2=A0 =C2=A0</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: #008;" class=3D"styled-by-prettify">u=
sing</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> type =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">template</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> collapse</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">using</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> type </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </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: #008;" class=3D"styled-by-prettify">temp=
late</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> collapse</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&amp;&amp;&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </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: #008;" class=3D"styled-by-prettify">using</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> type </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&amp;&amp;;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><code class=3D"prettyprint"><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">template</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> collapse</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">* &gt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">using</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> type </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=C2=A0 ;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"></span></code></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint">=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"pr=
ettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify"> // Op=
timization for trivial types </span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span></code></span></code></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">usin=
g</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0co=
llapse_t </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 style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> collapse</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify">type</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br><br></span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">class</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> T</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: #008;" class=3D"styled-by-prettify">struct</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Helper</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">operator</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">collapse_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> t</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</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: #000;" class=3D=
"styled-by-prettify"><br>=C2=A0 =C2=A0 bar</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"sty=
led-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">t</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=
: #800;" class=3D"styled-by-prettify">// What do you do here?</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">&gt;</span><span style=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"color: #000;" class=3D"styled-by-prettify"> foo</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> t</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: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Helper</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;{}(</spa=
n><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">forward</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">t</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"></span>=
<br></div></code></div></div><div>=C2=A0</div><div>In this example, you hav=
e no actual reference collapsing. And you cannot implement it with referenc=
e collapsing only, as you need the specialization for pointers.</div><div>T=
his is the kind of code I&#39;m worried about with your operator.</div><div=
>And it should work the same if, for whatever reason I change it back to so=
me simpler implementation using reference collapsing.</div><div>Reference c=
ollapsing is transparent!<br></div><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div><span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px"><span style=3D"display:inline!important;floa=
t:none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norma=
l;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left=
;text-decoration:none;text-indent:0px;text-transform:none;white-space:norma=
l;word-spacing:0px"><br></span></span></div><div><span style=3D"display:inl=
ine!important;float:none;background-color:transparent;color:rgb(34,34,34);f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:norm=
al;text-align:left;text-decoration:none;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px"><span style=3D"display:inline!importa=
nt;float:none;background-color:transparent;color:rgb(34,34,34);font-family:=
&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-styl=
e:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:left;text-decoration:none;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px">In a forwarding ref case the compiler will alway=
s use &#39;give&#39; (as was in the example!), <i>not matter what the forwa=
rding reference collapses to!</i></span></span></div></div></blockquote><bl=
ockquote 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><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px"><span style=3D"display=
:inline!important;float:none;background-color:transparent;color:rgb(34,34,3=
4);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size=
:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:=
normal;text-align:left;text-decoration:none;text-indent:0px;text-transform:=
none;white-space:normal;word-spacing:0px"><i></i><i></i><i></i><br></span><=
/span></div><div><span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant=
:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorati=
on:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px"><span style=3D"display:inline!important;float:none;background-color:t=
ransparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetic=
a&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fon=
t-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;tex=
t-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">The c=
ompiler will only EVER use &#39;giveref&#39; to cast a real lvalue (T&amp;&=
amp; is not an lvalue anyway)</span></span></div></div></blockquote><div><b=
r></div><div>T&amp;&amp; might be an lvalue reference.<br></div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><s=
pan style=3D"display:inline!important;float:none;background-color:transpare=
nt;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,=
sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight=
:400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px"><br></span></span></di=
v><div><span style=3D"display:inline!important;float:none;background-color:=
transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><spa=
n style=3D"display:inline!important;float:none;background-color:transparent=
;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sa=
ns-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:4=
00;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0=
px;text-transform:none;white-space:normal;word-spacing:0px">I believe this =
will work <i>all the time</i>, given current prerequisites - to be <i>as-if=
</i> move or forward is used correctly.=C2=A0</span></span></div><div><span=
 style=3D"display:inline!important;float:none;background-color:transparent;=
color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:40=
0;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0p=
x;text-transform:none;white-space:normal;word-spacing:0px"><span style=3D"d=
isplay:inline!important;float:none;background-color:transparent;color:rgb(3=
4,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;fon=
t-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-sp=
acing:normal;text-align:left;text-decoration:none;text-indent:0px;text-tran=
sform:none;white-space:normal;word-spacing:0px"><br></span></span></div></d=
iv></blockquote><div><br></div><div>See my example above.<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=
><span style=3D"display:inline!important;float:none;background-color:transp=
arent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-wei=
ght:400;letter-spacing:normal;text-align:left;text-decoration:none;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span styl=
e=3D"display:inline!important;float:none;background-color:transparent;color=
:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;let=
ter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;tex=
t-transform:none;white-space:normal;word-spacing:0px"></span></span></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"><d=
iv><br></div><div>But if the identifier is not a reference, then moving is =
the correct thing to do. Actually, that&#39;s the current rule for <span st=
yle=3D"font-family:courier new,monospace">std::forward</span>:</div><div><s=
pan style=3D"font-family:courier new,monospace">...</span><code><span style=
=3D"color:#000"><br></span></code></div><div>It doesn&#39;t matter if <span=
 style=3D"font-family:courier new,monospace">i</span>, <span style=3D"font-=
family:courier new,monospace">j</span> or <span style=3D"font-family:courie=
r new,monospace">k</span> are local variables, function parameters, or even=
 result of functions: the result is the same.</div><div><br></div><div>If y=
ou really want to move <span style=3D"font-family:courier new,monospace">j<=
/span> in that case, I would say calling <span style=3D"font-family:courier=
 new,monospace">std::move(j)</span> explicitely is fine: this is clearly no=
t used very often, but should still be possible to do.</div><div><br></div>=
<div>In short, use <span style=3D"font-family:courier new,monospace">&amp;&=
amp;&gt;</span> when you want to give a variable/expression away.</div><div=
>And use <span style=3D"font-family:courier new,monospace">std::move</span>=
 if you always want move. (no change required to <span style=3D"font-family=
:courier new,monospace">std::move</span>)</div><div>Those are very consiste=
nt rules that can be applied blindly, and don&#39;t depend on the context (=
template code or regular code).</div><div>It only depends on the programmer=
 intent. And that&#39;s what we want. (At least, that&#39;s what I want)<br=
></div></div></blockquote><div><br></div><div><br></div><div>If we have to =
use both &amp;&amp;&gt; and move, we are back to where we stared - learn wh=
en to use what. forward vs move is now &amp;&amp;&gt; vs move=C2=A0</div></=
div></blockquote><div><br></div><div>This is not the same. &amp;&amp;&gt; a=
nd std::move are not for the same purpose:</div><div>&amp;&amp;&gt;: I don&=
#39;t use this object anymore.</div><div>std::move(): nobody uses this obje=
ct anymore (I promise), so the callee can do anything they want with it.</d=
iv><div><br></div><div>It appears that, when you own the object (either loc=
al variable, or rvalue reference), the two are the same, but that&#39;s it!=
</div><div>My feeling is, your operator will be used most of the time, even=
 where std::move is currently used. And <b>very</b> rarely, std::move will =
be required, like to implement std::swap.</div><div>=C2=A0</div><blockquote=
 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><br></div><div>All =
we changed are the default. Yes the new defaults are nice, safe, but I want=
 <i>one</i>=C2=A0<span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&qu=
ot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant=
:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decorati=
on:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing=
:0px">keyword/operator, that <b>Just Works</b> (TM), so the user will no lo=
nger need to learn anything, expect &quot;this is how give objects&quot;.</=
span></div><div><span style=3D"display:inline!important;float:none;backgrou=
nd-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quo=
t;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:=
normal;font-weight:400;letter-spacing:normal;text-align:left;text-decoratio=
n:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px"><br></span></div><div><span style=3D"display:inline!important;float:no=
ne;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fo=
nt-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;tex=
t-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wo=
rd-spacing:0px">All the nuances are gone for good.=C2=A0</span></div></div>=
</blockquote><div><br></div><div>But you will have some cases where it won&=
#39;t work (see my example).<br></div><div>=C2=A0</div><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><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px"><br></span></div><div><span style=3D"di=
splay:inline!important;float:none;background-color:transparent;color:rgb(34=
,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font=
-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spa=
cing:normal;text-align:left;text-decoration:none;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px">&quot;This is how you give o=
bjects&quot;.=C2=A0</span><br></div><div><span style=3D"display:inline!impo=
rtant;float:none;background-color:transparent;color:rgb(34,34,34);font-fami=
ly:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-s=
tyle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-=
align:left;text-decoration:none;text-indent:0px;text-transform:none;white-s=
pace:normal;word-spacing:0px">&quot;Given object are not to be used.&quot;<=
/span></div></div></blockquote><div><br></div><div>&quot;This is how you te=
ll you don&#39;t need objects anymore&quot;</div><div><br></div><div>std::m=
ove is not for that. In a way, <span style=3D"font-family: courier new, mon=
ospace;">std::move</span> will be to <span style=3D"font-family: courier ne=
w, monospace;">&amp;&amp;&gt;</span> what <span style=3D"font-family: couri=
er new, monospace;">const_cast</span> is to <span style=3D"font-family: cou=
rier new, monospace;">static_cast</span>.<br></div><div><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=
><span style=3D"display:inline!important;float:none;background-color:transp=
arent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-wei=
ght:400;letter-spacing:normal;text-align:left;text-decoration:none;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></span=
></div><div><span style=3D"text-align:left;color:rgb(34,34,34);text-transfo=
rm:none;text-indent:0px;letter-spacing:normal;font-family:&quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-variant:normal;word-s=
pacing:0px;display:inline!important;white-space:normal;float:none;backgroun=
d-color:transparent"><span style=3D"display:inline!important;float:none;bac=
kground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-var=
iant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-deco=
ration:none;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px">This is all a user needs to know to use objects correctly.</span>=
</span><br></div><div><span style=3D"display:inline!important;float:none;ba=
ckground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-va=
riant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-dec=
oration:none;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px"><br></span></div><div><span style=3D"display:inline!important;fl=
oat:none;background-color:transparent;color:rgb(34,34,34);font-family:&quot=
;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:nor=
mal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:le=
ft;text-decoration:none;text-indent:0px;text-transform:none;white-space:nor=
mal;word-spacing:0px">An intermediate user will learn that</span></div><div=
><span style=3D"display:inline!important;float:none;background-color:transp=
arent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-wei=
ght:400;letter-spacing:normal;text-align:left;text-decoration:none;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px">&quot;If t=
he object you have given was yours (local copy) or was a reference to one t=
hat was about to die (concrete_type&amp;&amp;) you can reuse its name to pl=
ace a different object.&quot;</span></div><div><span style=3D"text-align:le=
ft;color:rgb(34,34,34);text-transform:none;text-indent:0px;letter-spacing:n=
ormal;font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-s=
ize:13px;font-variant:normal;word-spacing:0px;display:inline!important;whit=
e-space:normal;float:none;background-color:transparent"><span><span>&quot;<=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px">Given object=
s</span> are moved if they can and copied if they can not.&quot;=C2=A0</spa=
n></span><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br></=
span></div></div></blockquote><div><br></div><div>I completely agree with t=
hose. That&#39;s why I think <span style=3D"font-family: courier new, monos=
pace;">&amp;&amp;&gt;</span> should not move lvalue references: you don&#39=
;t own them.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><span style=3D"text-align:left;color:rgb(34,=
34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-va=
riant:normal;word-spacing:0px;display:inline!important;white-space:normal;f=
loat:none;background-color:transparent"></span></div><div><span style=3D"di=
splay:inline!important;float:none;background-color:transparent;color:rgb(34=
,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font=
-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spa=
cing:normal;text-align:left;text-decoration:none;text-indent:0px;text-trans=
form:none;white-space:normal;word-spacing:0px"><b></b><i></i><u></u><sub></=
sub><sup></sup><strike></strike><br></span></div><div><span style=3D"displa=
y:inline!important;float:none;background-color:transparent;color:rgb(34,34,=
34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-siz=
e:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing=
:normal;text-align:left;text-decoration:none;text-indent:0px;text-transform=
:none;white-space:normal;word-spacing:0px">That&#39;s it. No new rules just=
 streamline of the already established practice!=C2=A0</span></div><div><br=
></div><div></div><div>=C2=A0</div></div></blockquote><div>It&#39;s better =
to have &quot;user rules&quot; that give consitent behaviours, than &quot;n=
o user rules&quot; giving inconsistent results depending where it is used.<=
br></div><div>=C2=A0</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/b685630b-f20d-4a07-b85e-fce4c287525d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b685630b-f20d-4a07-b85e-fce4c287525d=
%40isocpp.org</a>.<br />

------=_Part_87800_2066597840.1528643376738--

------=_Part_87799_787017934.1528643376737--

.


Author: mihailnajdenov@gmail.com
Date: Sun, 10 Jun 2018 09:30:45 -0700 (PDT)
Raw View
------=_Part_88246_1081735159.1528648245122
Content-Type: multipart/alternative;
 boundary="----=_Part_88247_1235833774.1528648245124"

------=_Part_88247_1235833774.1528648245124
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>
>>
>>
>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com wrote:
>>>
>>>
>>>
>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9c=
rit :
>>>>
>>>> Ok, now it is all clear.
>>>>
>>>> The problem is forward is used not only to pass along a forward=20
>>>> reference, but also as to tool to trigger reference collapsing.=20
>>>>
>>>> Now the question is should a unified operator also being able to do=20
>>>> that. I think the answer is YES - after all it is intended to be a dro=
p-in=20
>>>> replacement for both forward and move, no matter the use case.
>>>>
>>>>
>>>> And I think it is actually simpler then initially thought.
>>>>
>>>>
>>>> The heuristic is as follows - IFF an identifier is a lvalue reference =
-=20
>>>> "move", in all other cases "forward".=20
>>>> This might sound counterintuitive, but, given current language rules -=
=20
>>>> it woks in all cases.
>>>>
>>>>
>>> This doesn't work with "forwarding" references:
>>> template <class T>
>>> void foo(T&& t) { bar(t&&>); }
>>>
>>> int i =3D 0;
>>> foo(i); // foo<int&>(i) and decltype(t) -> int&
>>> In this case, t within foo is an identifier whose type is an lvalue=20
>>> reference, but where the correct behaviour is (most of the time) forwar=
d,=20
>>> not move.
>>> You don't want this l-value reference being transformed into a rvalue=
=20
>>> reference.
>>>
>>
>>
>> By lvalue reference I meant real lvalue reference NOT the result of=20
>> collapsing!=20
>>
>
> But you can always imagine some meta-function that give the same result a=
s=20
> reference collapsing without relying on reference collapsing, and that=20
> being used as a function parameter.
> Reference collapsing is a bit like "forwarding" reference: once it has=20
> happened, it should behave the same as if never happened in the first pla=
ce=20
> if the types are equals.
>
> template <class T> struct collapse      { using type =3D T&&; };
> template <class T> struct collapse<T& > { using type =3D T& ; };
> template <class T> struct collapse<T&&> { using type =3D T&&; };
> template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
> Optimization for trivial types=20
> template <class T> using  collapse_t =3D typename collapse<T>::type;
>
>
> template <class T>
> struct Helper {
>   void operator()(collapse_t<T> t) {
>     bar(std::forward<T>(t)); // What do you do here?
> };
>
> template <class T>
> void foo(T&& t) {
>   Helper<T>{}(std::forward<T>(t));
> }
> =20
>


In this case you are forwarding as a different type. This is the reason=20
std::forward will not be deprecated.=20
And as a nice side effect - we can finally explain to a beginner why does=
=20
forward need a template argument - to be able to forward as different type!=
=20
(a cop out, =E2=80=A6 or may be not)


=20

> In this example, you have no actual reference collapsing. And you cannot=
=20
> implement it with reference collapsing only, as you need the specializati=
on=20
> for pointers.
> This is the kind of code I'm worried about with your operator.
> And it should work the same if, for whatever reason I change it back to=
=20
> some simpler implementation using reference collapsing.
> Reference collapsing is transparent!
>
>
>> In a forwarding ref case the compiler will always use 'give' (as was in=
=20
>> the example!), *not matter what the forwarding reference collapses to!*
>>
>
>> The compiler will only EVER use 'giveref' to cast a real lvalue (T&& is=
=20
>> not an lvalue anyway)
>>
>
> T&& might be an lvalue reference.
>

As per definition it is "rvalue reference to a cv-unqualified template=20
parameter".=20
Yeah, given T&& x, decltype(x) might be const &, but that is after=20
collapsing.=20

As said the compiler will always static_cast<T&&> when he sees T&&, =E2=80=
=A6 or=20
any && for that matter, =E2=80=A6 and even if no reference is present.=20

The compiler will need to remove_reference only in the case of casting real=
=20
lvalue reference to rvalue.=20
=20

> =20
>
>>
>> I believe this will work *all the time*, given current prerequisites -=
=20
>> to be *as-if* move or forward is used correctly.=20
>>
>>
> See my example above.
> =20
>
>> =20
>>
>>>
>>> But if the identifier is not a reference, then moving is the correct=20
>>> thing to do. Actually, that's the current rule for std::forward:
>>> ...
>>> It doesn't matter if i, j or k are local variables, function=20
>>> parameters, or even result of functions: the result is the same.
>>>
>>> If you really want to move j in that case, I would say calling=20
>>> std::move(j) explicitely is fine: this is clearly not used very often,=
=20
>>> but should still be possible to do.
>>>
>>> In short, use &&> when you want to give a variable/expression away.
>>> And use std::move if you always want move. (no change required to=20
>>> std::move)
>>> Those are very consistent rules that can be applied blindly, and don't=
=20
>>> depend on the context (template code or regular code).
>>> It only depends on the programmer intent. And that's what we want. (At=
=20
>>> least, that's what I want)
>>>
>>
>>
>> If we have to use both &&> and move, we are back to where we stared -=20
>> learn when to use what. forward vs move is now &&> vs move=20
>>
>
> This is not the same. &&> and std::move are not for the same purpose:
> &&>: I don't use this object anymore.
> std::move(): nobody uses this object anymore (I promise), so the callee=
=20
> can do anything they want with it.
>


You have a point.=20
And I really do appreciate this alternative views.=20
I for example initially considered proposing to forbid moving from const &=
=20
(fails to compile) because it is confusing and a code-lie.
I also considered move to be always move_if_noexcept instead.

But I deliberately dropped ALL "new ideas" and focused on "pure wins" in=20
the form "better ways to do the old stuff" - move and forward under one=20
no-decision syntax.=20
(Now that I think about it I haven't completely dropped move_if_noexcept,=
=20
but I have not studied it)


Besides, given

auto& a =3D geta();

These two would be equivalent.=20

oms(a&&>);
oms(a);=20

This is bad, the user is explicit he what it moved, if he does not, he=20
would have used the second syntax.

What are the options? Make it fail to compile, so the user must use=20
std::move.=20
Ok, but than the user will be just as annoyed he has to use some different=
=20
syntax so that he achieve the same thing in the end.
After all *he is already explicit*, being *also* explicit *in a special=20
way, *and *in a special case* can bit too much and my objective is=20
streamlining.=20



> It appears that, when you own the object (either local variable, or rvalu=
e=20
> reference), the two are the same, but that's it!
> My feeling is, your operator will be used most of the time, even where=20
> std::move is currently used. And *very* rarely, std::move will be=20
> required, like to implement std::swap.
> =20
>
>>
>> All we changed are the default. Yes the new defaults are nice, safe, but=
=20
>> I want *one* keyword/operator, that *Just Works* (TM), so the user will=
=20
>> no longer need to learn anything, expect "this is how give objects".
>>
>> All the nuances are gone for good.=20
>>
>
> But you will have some cases where it won't work (see my example).
> =20
>
>>
>> "This is how you give objects".=20
>> "Given object are not to be used."
>>
>
> "This is how you tell you don't need objects anymore"
>
> std::move is not for that. In a way, std::move will be to &&> what=20
> const_cast is to static_cast.
>
> =20
>
>>
>> This is all a user needs to know to use objects correctly.
>>
>> An intermediate user will learn that
>> "If the object you have given was yours (local copy) or was a reference=
=20
>> to one that was about to die (concrete_type&&) you can reuse its name to=
=20
>> place a different object."
>> "Given objects are moved if they can and copied if they can not."=20
>>
>
> I completely agree with those. That's why I think &&> should not move=20
> lvalue references: you don't own them.
> =20
>
>>
>> That's it. No new rules just streamline of the already established=20
>> practice!=20
>>
>> =20
>>
> It's better to have "user rules" that give consitent behaviours, than "no=
=20
> user rules" giving inconsistent results depending where it is used.
> =20
>

--=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/7f456d66-51c3-4072-bdfc-6dd75f03913b%40isocpp.or=
g.

------=_Part_88247_1235833774.1528648245124
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, flor=
ia...@gmail.com 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"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.=
com</a> 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"><div dir=
=3D"ltr"><div>Ok, now it is all clear.</div><div><br></div><div>The problem=
 is forward is used not only to pass along a forward reference, but also as=
 to tool to trigger reference collapsing.=C2=A0</div><div><br></div><div>No=
w the question is should a unified operator also being able to do that. I t=
hink the answer is YES - after all it is intended to be a drop-in replaceme=
nt for both forward and move, no matter the use case.</div><div><br></div><=
div><br>And I think it is actually simpler then initially thought.</div><di=
v><br></div><div><br></div><div>The heuristic is as follows - IFF an identi=
fier is a lvalue reference - &quot;move&quot;, in all other cases &quot;for=
ward&quot;. </div><div>This might sound counterintuitive, but, given curren=
t language rules - it woks in all cases.</div><div><br></div></div></blockq=
uote><div><br></div><div>This doesn&#39;t work with &quot;forwarding&quot; =
references:<br></div><div><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class<=
/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:#660">(</s=
pan><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&amp=
;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><=
span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">t</span><span style=3D"color:#660">&amp;&amp;&gt;);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</spa=
n><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">int<=
/span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span>=
<span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000">i</span><spa=
n style=3D"color:#660">);</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#800">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; int&amp;=
</span><span style=3D"color:#000"><br></span></div></code></div>In this cas=
e, t within foo is an identifier whose type is an lvalue reference, but whe=
re the correct behaviour is (most of the time) forward, not move.</div><div=
>You don&#39;t want this l-value reference being transformed into a rvalue =
reference.</div></div></blockquote><div><br></div><div><br></div><div>By <s=
pan style=3D"display:inline!important;float:none;background-color:transpare=
nt;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,=
sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight=
:400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px">lvalue refere=
nce I meant real=C2=A0<span style=3D"display:inline!important;float:none;ba=
ckground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-va=
riant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-dec=
oration:none;text-indent:0px;text-transform:none;white-space:normal;word-sp=
acing:0px">lvalue reference NOT the result of collapsing!=C2=A0</span></spa=
n></div></div></blockquote><div><br></div><div>But you can always imagine s=
ome meta-function that give the same result as reference collapsing without=
 relying on reference collapsing, and that being used as a function paramet=
er.</div><div>Reference collapsing is a bit like &quot;forwarding&quot; ref=
erence: once it has happened, it should behave the same as if never happene=
d in the first place if the types are equals.</div><div><br></div><div><div=
 style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);b=
order-style:solid;border-width:1px"><code><div><span style=3D"color:#008">t=
emplate</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#00=
0"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">struct</span><span style=3D"color:#000=
"> collapse =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">{</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">using</span><s=
pan style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</span>=
<span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;&amp;;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">template=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</=
span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">struct</span><span style=3D"color:#000"> coll=
apse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000"=
>T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">using</span><span style=3D"color:#000"> type </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</sp=
an><span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">template</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span>=
<span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><=
span style=3D"color:#000"> collapse</span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&am=
p;&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">using=
</span><span style=3D"color:#000"> type </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&a=
mp;&amp;;</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"><code><span style=3D"color:#000"><br=
></span><span style=3D"color:#008">template</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">=
class</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">=
&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">st=
ruct</span><span style=3D"color:#000"> collapse</span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#6=
60">* &gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">u=
sing</span><span style=3D"color:#000"> type </span><span style=3D"color:#66=
0">=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#660"=
>=C2=A0 ;</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"></span></code></span><span style=3D"=
color:#000"><code><span style=3D"color:#000"><code><span style=3D"color:#80=
0"> // Optimization for trivial types </span><span style=3D"color:#000"><br=
></span></code></span></code></span><span style=3D"color:#008">template</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span=
><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</span=
><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><=
span style=3D"color:#008">using</span><span style=3D"color:#000"> =C2=A0col=
lapse_t </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">typename</span><span style=3D"color:=
#000"> collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"=
color:#000">T</span><span style=3D"color:#660">&gt;::</span><span style=3D"=
color:#000">type</span><span style=3D"color:#660">;</span><span style=3D"co=
lor:#000"><br><br><br></span><span style=3D"color:#008">template</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span =
style=3D"color:#008">class</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">struct</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#606">Helper</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span>=
<span style=3D"color:#008">void</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">operator</span><span style=3D"color:#660">()(</spa=
n><span style=3D"color:#000">collapse_t</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><s=
pan style=3D"color:#000"><br>=C2=A0 =C2=A0 bar</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">forward</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660=
">&gt;(</span><span style=3D"color:#000">t</span><span style=3D"color:#660"=
>));</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//=
 What do you do here?</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span><span =
style=3D"color:#008">template</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><s=
pan style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#008">void</span><s=
pan style=3D"color:#000"> foo</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&amp;</span>=
<span style=3D"color:#000"> t</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#606">Helper</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><=
span style=3D"color:#660">&gt;{}(</span><span style=3D"color:#000">std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</s=
pan><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</spa=
n><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">t</span=
><span style=3D"color:#660">)<wbr>);</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#660">}</span><span style=3D"color:#000"></span>=
<br></div></code></div></div><div>=C2=A0</div></div></blockquote><div><br><=
/div><div><br></div><div>In this case you are forwarding as a different typ=
e. This is the reason std::forward will not be deprecated.=C2=A0</div><div>=
And as a nice side effect - we can finally explain to a beginner why does f=
orward need a template argument - to be able to forward as different type! =
(a cop out, =E2=80=A6 or may be not)</div><div><br></div><div><br></div><di=
v>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div>In this example, you have no actual reference collapsing. And you can=
not implement it with reference collapsing only, as you need the specializa=
tion for pointers.</div><div>This is the kind of code I&#39;m worried about=
 with your operator.</div><div>And it should work the same if, for whatever=
 reason I change it back to some simpler implementation using reference col=
lapsing.</div><div>Reference collapsing is transparent!<br></div><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><span st=
yle=3D"display:inline!important;float:none;background-color:transparent;col=
or:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-s=
erif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;l=
etter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;t=
ext-transform:none;white-space:normal;word-spacing:0px"><span style=3D"disp=
lay:inline!important;float:none;background-color:transparent;color:rgb(34,3=
4,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-s=
ize:13px;font-style:normal;font-variant:normal;font-weight:400;letter-spaci=
ng:normal;text-align:left;text-decoration:none;text-indent:0px;text-transfo=
rm:none;white-space:normal;word-spacing:0px"><br></span></span></div><div><=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px">In a forwarding ref ca=
se the compiler will always use &#39;give&#39; (as was in the example!), <i=
>not matter what the forwarding reference collapses to!</i></span></span></=
div></div></blockquote><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><span style=3D"display:inline!important;float:none;background-col=
or:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helv=
etica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal=
;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:none=
;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><=
span style=3D"display:inline!important;float:none;background-color:transpar=
ent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;=
,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weigh=
t:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inden=
t:0px;text-transform:none;white-space:normal;word-spacing:0px"><i></i><i></=
i><i></i><br></span></span></div><div><span style=3D"display:inline!importa=
nt;float:none;background-color:transparent;color:rgb(34,34,34);font-family:=
&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-styl=
e:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:left;text-decoration:none;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px"><span style=3D"display:inline!important;float:no=
ne;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fo=
nt-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;tex=
t-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wo=
rd-spacing:0px">The compiler will only EVER use &#39;giveref&#39; to cast a=
 real lvalue (T&amp;&amp; is not an lvalue anyway)</span></span></div></div=
></blockquote><div><br></div><div>T&amp;&amp; might be an lvalue reference.=
<br></div></div></blockquote><div><br></div><div>As per definition it is &q=
uot;rvalue reference to a cv-unqualified template parameter&quot;.=C2=A0</d=
iv><div>Yeah, given <font face=3D"courier new,monospace">T&amp;&amp; x, dec=
ltype(x)</font> might be <font face=3D"courier new,monospace">const &amp;</=
font>, but that is after collapsing.=C2=A0</div><div><br></div><div>As said=
 the compiler will always static_cast&lt;T&amp;&amp;&gt; when he sees T&amp=
;&amp;, =E2=80=A6 or any &amp;&amp; for that matter, =E2=80=A6 and even if =
no reference is present.=C2=A0</div><div><br></div><div>The compiler will n=
eed to remove_reference only in the case of casting real lvalue reference t=
o rvalue.=C2=A0</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><div></div><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><span style=3D"display:inline!impor=
tant;float:none;background-color:transparent;color:rgb(34,34,34);font-famil=
y:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-st=
yle:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-a=
lign:left;text-decoration:none;text-indent:0px;text-transform:none;white-sp=
ace:normal;word-spacing:0px"><span style=3D"display:inline!important;float:=
none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;=
font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;t=
ext-decoration:none;text-indent:0px;text-transform:none;white-space:normal;=
word-spacing:0px"><br></span></span></div><div><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px"><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px">I believe this will work <i>all the time</i>, give=
n current prerequisites - to be <i>as-if</i> move or forward is used correc=
tly.=C2=A0</span></span></div><div><span style=3D"display:inline!important;=
float:none;background-color:transparent;color:rgb(34,34,34);font-family:&qu=
ot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:n=
ormal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:=
left;text-decoration:none;text-indent:0px;text-transform:none;white-space:n=
ormal;word-spacing:0px"><span style=3D"display:inline!important;float:none;=
background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&qu=
ot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-=
variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-d=
ecoration:none;text-indent:0px;text-transform:none;white-space:normal;word-=
spacing:0px"><br></span></span></div></div></blockquote><div><br></div><div=
>See my example above.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><span style=3D"display:inline!important=
;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&q=
uot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:=
normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align=
:left;text-decoration:none;text-indent:0px;text-transform:none;white-space:=
normal;word-spacing:0px"><span style=3D"display:inline!important;float:none=
;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&q=
uot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font=
-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-=
decoration:none;text-indent:0px;text-transform:none;white-space:normal;word=
-spacing:0px"></span></span></div><div>=C2=A0</div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div><br></div><div>But if the identifier =
is not a reference, then moving is the correct thing to do. Actually, that&=
#39;s the current rule for <span style=3D"font-family:courier new,monospace=
">std::forward</span>:</div><div><span style=3D"font-family:courier new,mon=
ospace">...</span><code><span style=3D"color:#000"><br></span></code></div>=
<div>It doesn&#39;t matter if <span style=3D"font-family:courier new,monosp=
ace">i</span>, <span style=3D"font-family:courier new,monospace">j</span> o=
r <span style=3D"font-family:courier new,monospace">k</span> are local vari=
ables, function parameters, or even result of functions: the result is the =
same.</div><div><br></div><div>If you really want to move <span style=3D"fo=
nt-family:courier new,monospace">j</span> in that case, I would say calling=
 <span style=3D"font-family:courier new,monospace">std::move(j)</span> expl=
icitely is fine: this is clearly not used very often, but should still be p=
ossible to do.</div><div><br></div><div>In short, use <span style=3D"font-f=
amily:courier new,monospace">&amp;&amp;&gt;</span> when you want to give a =
variable/expression away.</div><div>And use <span style=3D"font-family:cour=
ier new,monospace">std::move</span> if you always want move. (no change req=
uired to <span style=3D"font-family:courier new,monospace">std::move</span>=
)</div><div>Those are very consistent rules that can be applied blindly, an=
d don&#39;t depend on the context (template code or regular code).</div><di=
v>It only depends on the programmer intent. And that&#39;s what we want. (A=
t least, that&#39;s what I want)<br></div></div></blockquote><div><br></div=
><div><br></div><div>If we have to use both &amp;&amp;&gt; and move, we are=
 back to where we stared - learn when to use what. forward vs move is now &=
amp;&amp;&gt; vs move=C2=A0</div></div></blockquote><div><br></div><div>Thi=
s is not the same. &amp;&amp;&gt; and std::move are not for the same purpos=
e:</div><div>&amp;&amp;&gt;: I don&#39;t use this object anymore.</div><div=
>std::move(): nobody uses this object anymore (I promise), so the callee ca=
n do anything they want with it.</div></div></blockquote><div><br></div><di=
v><br></div><div>You have a point.=C2=A0</div><div>And I really do apprecia=
te this alternative views.=C2=A0</div><div>I for example initially consider=
ed proposing to forbid moving from const &amp; (fails to compile) because i=
t is confusing and a code-lie.</div><div>I also considered move to be alway=
s move_if_noexcept instead.</div><div><br></div><div>But I deliberately dro=
pped ALL &quot;new ideas&quot; and focused on &quot;pure wins&quot; in the =
form &quot;better ways to do the old stuff&quot; - move and forward under o=
ne no-decision syntax.=C2=A0<br></div><div>(Now that I think about it I hav=
en&#39;t completely dropped <span style=3D"display: inline !important; floa=
t: none; background-color: transparent; color: rgb(34, 34, 34); font-family=
: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font=
-style: normal; font-variant: normal; font-weight: 400; letter-spacing: nor=
mal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px;=
 text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal;=
 word-spacing: 0px;">move_if_noexcept, but I have not studied it</span>)</d=
iv><div><br></div><div><br></div><div>Besides, given</div><div><br></div><d=
iv><font face=3D"courier new,monospace">auto&amp; a =3D geta();</font></div=
><div><font face=3D"courier new,monospace"><br></font></div><div>These two =
would be equivalent.=C2=A0</div><div><br></div><div><font face=3D"courier n=
ew,monospace">oms(a&amp;&amp;&gt;);</font></div><div><font face=3D"courier =
new,monospace">oms(a);=C2=A0</font></div><div><font face=3D"courier new,mon=
ospace"><br></font></div><div><font face=3D"arial,sans-serif">This is bad, =
the user is explicit he what it moved, if he does not, he would have used t=
he second syntax.</font></div><div><font face=3D"arial,sans-serif"><br></fo=
nt></div><div><font face=3D"arial,sans-serif">What are the options? Make it=
 fail to compile, so the user must use std::move.=C2=A0</font></div><div><f=
ont face=3D"arial,sans-serif">Ok, but than the user will be just as annoyed=
 he has to use some different syntax so that he achieve the same thing in t=
he end.</font></div><div><font face=3D"arial,sans-serif">After all <i>he is=
 already explicit</i>, being <i>also</i> explicit <i>in a special way, </i>=
and <i>in a special case</i> can bit too much and my objective is streamlin=
ing.=C2=A0</font></div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>It appears that=
, when you own the object (either local variable, or rvalue reference), the=
 two are the same, but that&#39;s it!</div><div>My feeling is, your operato=
r will be used most of the time, even where std::move is currently used. An=
d <b>very</b> rarely, std::move will be required, like to implement std::sw=
ap.</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><div>All we changed are the default. Yes the new de=
faults are nice, safe, but I want <i>one</i>=C2=A0<span style=3D"display:in=
line!important;float:none;background-color:transparent;color:rgb(34,34,34);=
font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13=
px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:nor=
mal;text-align:left;text-decoration:none;text-indent:0px;text-transform:non=
e;white-space:normal;word-spacing:0px">keyword/operator, that <b>Just Works=
</b> (TM), so the user will no longer need to learn anything, expect &quot;=
this is how give objects&quot;.</span></div><div><span style=3D"display:inl=
ine!important;float:none;background-color:transparent;color:rgb(34,34,34);f=
ont-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13p=
x;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:norm=
al;text-align:left;text-decoration:none;text-indent:0px;text-transform:none=
;white-space:normal;word-spacing:0px"><br></span></div><div><span style=3D"=
display:inline!important;float:none;background-color:transparent;color:rgb(=
34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;fo=
nt-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-s=
pacing:normal;text-align:left;text-decoration:none;text-indent:0px;text-tra=
nsform:none;white-space:normal;word-spacing:0px">All the nuances are gone f=
or good.=C2=A0</span></div></div></blockquote><div><br></div><div>But you w=
ill have some cases where it won&#39;t work (see my example).<br></div><div=
>=C2=A0</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>=
<span style=3D"display:inline!important;float:none;background-color:transpa=
rent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot=
;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weig=
ht:400;letter-spacing:normal;text-align:left;text-decoration:none;text-inde=
nt:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></span>=
</div><div><span style=3D"display:inline!important;float:none;background-co=
lor:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:norma=
l;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:non=
e;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">=
&quot;This is how you give objects&quot;.=C2=A0</span><br></div><div><span =
style=3D"display:inline!important;float:none;background-color:transparent;c=
olor:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400=
;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px=
;text-transform:none;white-space:normal;word-spacing:0px">&quot;Given objec=
t are not to be used.&quot;</span></div></div></blockquote><div><br></div><=
div>&quot;This is how you tell you don&#39;t need objects anymore&quot;</di=
v><div><br></div><div>std::move is not for that. In a way, <span style=3D"f=
ont-family:courier new,monospace">std::move</span> will be to <span style=
=3D"font-family:courier new,monospace">&amp;&amp;&gt;</span> what <span sty=
le=3D"font-family:courier new,monospace">const_cast</span> is to <span styl=
e=3D"font-family:courier new,monospace">static_cast</span>.<br></div><div><=
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><span style=3D"display:inline!important;float:none;background=
-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:no=
rmal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:=
none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x"><br></span></div><div><span style=3D"text-align:left;color:rgb(34,34,34)=
;text-transform:none;text-indent:0px;letter-spacing:normal;font-family:&quo=
t;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-variant:=
normal;word-spacing:0px;display:inline!important;white-space:normal;float:n=
one;background-color:transparent"><span style=3D"display:inline!important;f=
loat:none;background-color:transparent;color:rgb(34,34,34);font-family:&quo=
t;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:no=
rmal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:l=
eft;text-decoration:none;text-indent:0px;text-transform:none;white-space:no=
rmal;word-spacing:0px">This is all a user needs to know to use objects corr=
ectly.</span></span><br></div><div><span style=3D"display:inline!important;=
float:none;background-color:transparent;color:rgb(34,34,34);font-family:&qu=
ot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:n=
ormal;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:=
left;text-decoration:none;text-indent:0px;text-transform:none;white-space:n=
ormal;word-spacing:0px"><br></span></div><div><span style=3D"display:inline=
!important;float:none;background-color:transparent;color:rgb(34,34,34);font=
-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;f=
ont-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;=
text-align:left;text-decoration:none;text-indent:0px;text-transform:none;wh=
ite-space:normal;word-spacing:0px">An intermediate user will learn that</sp=
an></div><div><span style=3D"display:inline!important;float:none;background=
-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:no=
rmal;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:=
none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0p=
x">&quot;If the object you have given was yours (local copy) or was a refer=
ence to one that was about to die (concrete_type&amp;&amp;) you can reuse i=
ts name to place a different object.&quot;</span></div><div><span style=3D"=
text-align:left;color:rgb(34,34,34);text-transform:none;text-indent:0px;let=
ter-spacing:normal;font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif;font-size:13px;font-variant:normal;word-spacing:0px;display:inline!i=
mportant;white-space:normal;float:none;background-color:transparent"><span>=
<span>&quot;<span style=3D"display:inline!important;float:none;background-c=
olor:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:norm=
al;font-weight:400;letter-spacing:normal;text-align:left;text-decoration:no=
ne;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"=
>Given objects</span> are moved if they can and copied if they can not.&quo=
t;=C2=A0</span></span><b></b><i></i><u></u><sub></sub><sup></sup><strike></=
strike><br></span></div></div></blockquote><div><br></div><div>I completely=
 agree with those. That&#39;s why I think <span style=3D"font-family:courie=
r new,monospace">&amp;&amp;&gt;</span> should not move lvalue references: y=
ou don&#39;t own them.<br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><span style=3D"text-align:left;color:rg=
b(34,34,34);text-transform:none;text-indent:0px;letter-spacing:normal;font-=
family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;fo=
nt-variant:normal;word-spacing:0px;display:inline!important;white-space:nor=
mal;float:none;background-color:transparent"></span></div><div><span style=
=3D"display:inline!important;float:none;background-color:transparent;color:=
rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lett=
er-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text=
-transform:none;white-space:normal;word-spacing:0px"><b></b><i></i><u></u><=
sub></sub><sup></sup><strike></strike><br></span></div><div><span style=3D"=
display:inline!important;float:none;background-color:transparent;color:rgb(=
34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;fo=
nt-size:13px;font-style:normal;font-variant:normal;font-weight:400;letter-s=
pacing:normal;text-align:left;text-decoration:none;text-indent:0px;text-tra=
nsform:none;white-space:normal;word-spacing:0px">That&#39;s it. No new rule=
s just streamline of the already established practice!=C2=A0</span></div><d=
iv><br></div><div></div><div>=C2=A0</div></div></blockquote><div>It&#39;s b=
etter to have &quot;user rules&quot; that give consitent behaviours, than &=
quot;no user rules&quot; giving inconsistent results depending where it is =
used.<br></div><div>=C2=A0</div></div></blockquote></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/7f456d66-51c3-4072-bdfc-6dd75f03913b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7f456d66-51c3-4072-bdfc-6dd75f03913b=
%40isocpp.org</a>.<br />

------=_Part_88247_1235833774.1528648245124--

------=_Part_88246_1081735159.1528648245122--

.


Author: florian.csdt@gmail.com
Date: Sun, 10 Jun 2018 10:17:14 -0700 (PDT)
Raw View
------=_Part_56691_2004630572.1528651034595
Content-Type: multipart/alternative;
 boundary="----=_Part_56692_1136362514.1528651034596"

------=_Part_56692_1136362514.1528651034596
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9crit =
:
>
>
>
> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>>
>>>
>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com wrote=
:
>>>>
>>>>
>>>>
>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a =C3=A9=
crit :
>>>>>
>>>>> Ok, now it is all clear.
>>>>>
>>>>> The problem is forward is used not only to pass along a forward=20
>>>>> reference, but also as to tool to trigger reference collapsing.=20
>>>>>
>>>>> Now the question is should a unified operator also being able to do=
=20
>>>>> that. I think the answer is YES - after all it is intended to be a dr=
op-in=20
>>>>> replacement for both forward and move, no matter the use case.
>>>>>
>>>>>
>>>>> And I think it is actually simpler then initially thought.
>>>>>
>>>>>
>>>>> The heuristic is as follows - IFF an identifier is a lvalue reference=
=20
>>>>> - "move", in all other cases "forward".=20
>>>>> This might sound counterintuitive, but, given current language rules =
-=20
>>>>> it woks in all cases.
>>>>>
>>>>>
>>>> This doesn't work with "forwarding" references:
>>>> template <class T>
>>>> void foo(T&& t) { bar(t&&>); }
>>>>
>>>> int i =3D 0;
>>>> foo(i); // foo<int&>(i) and decltype(t) -> int&
>>>> In this case, t within foo is an identifier whose type is an lvalue=20
>>>> reference, but where the correct behaviour is (most of the time) forwa=
rd,=20
>>>> not move.
>>>> You don't want this l-value reference being transformed into a rvalue=
=20
>>>> reference.
>>>>
>>>
>>>
>>> By lvalue reference I meant real lvalue reference NOT the result of=20
>>> collapsing!=20
>>>
>>
>> But you can always imagine some meta-function that give the same result=
=20
>> as reference collapsing without relying on reference collapsing, and tha=
t=20
>> being used as a function parameter.
>> Reference collapsing is a bit like "forwarding" reference: once it has=
=20
>> happened, it should behave the same as if never happened in the first pl=
ace=20
>> if the types are equals.
>>
>> template <class T> struct collapse      { using type =3D T&&; };
>> template <class T> struct collapse<T& > { using type =3D T& ; };
>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
>> Optimization for trivial types=20
>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>
>>
>> template <class T>
>> struct Helper {
>>   void operator()(collapse_t<T> t) {
>>     bar(std::forward<T>(t)); // What do you do here?
>> };
>>
>> template <class T>
>> void foo(T&& t) {
>>   Helper<T>{}(std::forward<T>(t));
>> }
>> =20
>>
>
>
> In this case you are forwarding as a different type. This is the reason=
=20
> std::forward will not be deprecated.=20
> And as a nice side effect - we can finally explain to a beginner why does=
=20
> forward need a template argument - to be able to forward as different typ=
e!=20
> (a cop out, =E2=80=A6 or may be not)
>

In that example, I'm not forwarding as a different type. As far as the=20
compiler is concerned, I might be, but actually I'm not.
=20

>
>
> =20
>
>> In this example, you have no actual reference collapsing. And you cannot=
=20
>> implement it with reference collapsing only, as you need the specializat=
ion=20
>> for pointers.
>> This is the kind of code I'm worried about with your operator.
>> And it should work the same if, for whatever reason I change it back to=
=20
>> some simpler implementation using reference collapsing.
>> Reference collapsing is transparent!
>>
>>
>>> In a forwarding ref case the compiler will always use 'give' (as was in=
=20
>>> the example!), *not matter what the forwarding reference collapses to!*
>>>
>>
>>> The compiler will only EVER use 'giveref' to cast a real lvalue (T&& is=
=20
>>> not an lvalue anyway)
>>>
>>
>> T&& might be an lvalue reference.
>>
>
> As per definition it is "rvalue reference to a cv-unqualified template=20
> parameter".=20
> Yeah, given T&& x, decltype(x) might be const &, but that is after=20
> collapsing.=20
>

Here you're mixing the type declaration and the actual type.
A type declaration cannot be a "rvalue reference", it might declare a=20
rvalue reference though.
=20

>
> As said the compiler will always static_cast<T&&> when he sees T&&, =E2=
=80=A6 or=20
> any && for that matter, =E2=80=A6 and even if no reference is present.=20
>
> The compiler will need to remove_reference only in the case of casting=20
> real lvalue reference to rvalue.=20
> =20
>
>> =20
>>
>>>
>>> I believe this will work *all the time*, given current prerequisites -=
=20
>>> to be *as-if* move or forward is used correctly.=20
>>>
>>>
>> See my example above.
>> =20
>>
>>> =20
>>>
>>>>
>>>> But if the identifier is not a reference, then moving is the correct=
=20
>>>> thing to do. Actually, that's the current rule for std::forward:
>>>> ...
>>>> It doesn't matter if i, j or k are local variables, function=20
>>>> parameters, or even result of functions: the result is the same.
>>>>
>>>> If you really want to move j in that case, I would say calling=20
>>>> std::move(j) explicitely is fine: this is clearly not used very often,=
=20
>>>> but should still be possible to do.
>>>>
>>>> In short, use &&> when you want to give a variable/expression away.
>>>> And use std::move if you always want move. (no change required to=20
>>>> std::move)
>>>> Those are very consistent rules that can be applied blindly, and don't=
=20
>>>> depend on the context (template code or regular code).
>>>> It only depends on the programmer intent. And that's what we want. (At=
=20
>>>> least, that's what I want)
>>>>
>>>
>>>
>>> If we have to use both &&> and move, we are back to where we stared -=
=20
>>> learn when to use what. forward vs move is now &&> vs move=20
>>>
>>
>> This is not the same. &&> and std::move are not for the same purpose:
>> &&>: I don't use this object anymore.
>> std::move(): nobody uses this object anymore (I promise), so the callee=
=20
>> can do anything they want with it.
>>
>
>
> You have a point.=20
> And I really do appreciate this alternative views.=20
> I for example initially considered proposing to forbid moving from const =
&=20
> (fails to compile) because it is confusing and a code-lie.
> I also considered move to be always move_if_noexcept instead.
>

Your operator should not fail to compile. If there are cases where it does,=
=20
then it is completely useless for templates
=20

>
> But I deliberately dropped ALL "new ideas" and focused on "pure wins" in=
=20
> the form "better ways to do the old stuff" - move and forward under one=
=20
> no-decision syntax.=20
> (Now that I think about it I haven't completely dropped move_if_noexcept,=
=20
> but I have not studied it)
>
>
> Besides, given
>
> auto& a =3D geta();
>
> These two would be equivalent.=20
>
> oms(a&&>);
> oms(a);=20
>

Here, he is being explicit that he doesn't use a after a&&> (despite doing=
=20
it anyway, but I'm pretty sure you put the second line just for comparison)=
..
But the function that returned the reference in the first place might need=
=20
the object in the future. So it shouldn't be implicitly moved. That would=
=20
be dangerous.

However:
auto&& a =3D geta();
auto b =3D getb();

oms(a); // will use it afterwards
oms(a&&>); // will not use it afterwards
oms(b&&>); //will not use it afterwards
If a is a rvalue reference, a&&> will correctly move it.
If a happens to be a lvalue reference, it will not be moved, but just=20
forwarded as is.
As b cannot be a reference (that's how auto works), b will be moved: there=
=20
is no outside world.

Now:
auto&& a =3D geta();

oms(std::move(a));
Will move a even if a is an lvalue reference, even if the object was still=
=20
needed somewhere else (so to be used with caution).

=20

>
> This is bad, the user is explicit he what it moved, if he does not, he=20
> would have used the second syntax.
>
> What are the options? Make it fail to compile, so the user must use=20
> std::move.=20
>

Don't make it fail, it would defeat the whole purpose.
=20

> Ok, but than the user will be just as annoyed he has to use some differen=
t=20
> syntax so that he achieve the same thing in the end.
> After all *he is already explicit*, being *also* explicit *in a special=
=20
> way, *and *in a special case* can bit too much and my objective is=20
> streamlining.=20
>

He is being explicit about his code, not about the rest of the world. While=
=20
with std::move() he would be explicit about the whole world.
If he owns the object, his code is the whole world (as far as the object is=
=20
concerned), so that's fine.

If you consider the amount of code using std::forward and the amount of=20
code using std::move on lvalue references (not local objects), it is pretty=
=20
clear who the winner is.
=20

--=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/41662b6a-f5ce-4d03-a436-d43a75c4d3ab%40isocpp.or=
g.

------=_Part_56692_1136362514.1528651034596
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn..=
..@gmail.com a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <a>=
floria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@=
gmail.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>flo=
ria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>Ok, now it is all clear.</div><div><br></div><div>The prob=
lem is forward is used not only to pass along a forward reference, but also=
 as to tool to trigger reference collapsing.=C2=A0</div><div><br></div><div=
>Now the question is should a unified operator also being able to do that. =
I think the answer is YES - after all it is intended to be a drop-in replac=
ement for both forward and move, no matter the use case.</div><div><br></di=
v><div><br>And I think it is actually simpler then initially thought.</div>=
<div><br></div><div><br></div><div>The heuristic is as follows - IFF an ide=
ntifier is a lvalue reference - &quot;move&quot;, in all other cases &quot;=
forward&quot;. </div><div>This might sound counterintuitive, but, given cur=
rent language rules - it woks in all cases.</div><div><br></div></div></blo=
ckquote><div><br></div><div>This doesn&#39;t work with &quot;forwarding&quo=
t; references:<br></div><div><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">template</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cla=
ss</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">vo=
id</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&=
amp;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"> bar</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#000">t</span><span style=3D"color:#660">&amp;&amp;&gt=
;);</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">i=
nt</span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#000">i</span=
><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#800">// foo&lt;int&amp;&gt;(i) and decltype(t) -&gt; int=
&amp;</span><span style=3D"color:#000"><br></span></div></code></div>In thi=
s case, t within foo is an identifier whose type is an lvalue reference, bu=
t where the correct behaviour is (most of the time) forward, not move.</div=
><div>You don&#39;t want this l-value reference being transformed into a rv=
alue reference.</div></div></blockquote><div><br></div><div><br></div><div>=
By <span style=3D"display:inline!important;float:none;background-color:tran=
sparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-w=
eight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-i=
ndent:0px;text-transform:none;white-space:normal;word-spacing:0px">lvalue r=
eference I meant real=C2=A0<span style=3D"display:inline!important;float:no=
ne;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fo=
nt-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;tex=
t-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wo=
rd-spacing:0px">lvalue reference NOT the result of collapsing!=C2=A0</span>=
</span></div></div></blockquote><div><br></div><div>But you can always imag=
ine some meta-function that give the same result as reference collapsing wi=
thout relying on reference collapsing, and that being used as a function pa=
rameter.</div><div>Reference collapsing is a bit like &quot;forwarding&quot=
; reference: once it has happened, it should behave the same as if never ha=
ppened in the first place if the types are equals.</div><div><br></div><div=
><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,1=
87);border-style:solid;border-width:1px"><code><div><span style=3D"color:#0=
08">template</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">&lt;</span><span style=3D"color:#008">class</span><span style=3D"colo=
r:#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">struct</span><span style=3D"color=
:#000"> collapse =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">using</sp=
an><span style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;&a=
mp;;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">};=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> ty=
pe </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&amp;</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#008">template</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">struct</s=
pan><span style=3D"color:#000"> collapse</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&am=
p;&amp;&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
using</span><span style=3D"color:#000"> type </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">&amp;&amp;;</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">};</span><span style=3D"color:#000"><code><span style=3D"color:#000"=
><br></span><span style=3D"color:#008">template</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#0=
08">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#6=
60">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008=
">struct</span><span style=3D"color:#000"> collapse</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"colo=
r:#660">* &gt;</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">using</span><span style=3D"color:#000"> type </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#=
660">=C2=A0 ;</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">};</span><span style=3D"color:#000"></span></code></span><span style=
=3D"color:#000"><code><span style=3D"color:#000"><code><span style=3D"color=
:#800"> // Optimization for trivial types </span><span style=3D"color:#000"=
><br></span></code></span></code></span><span style=3D"color:#008">template=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</=
span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">using</span><span style=3D"color:#000"> =C2=
=A0collapse_t </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">typename</span><span style=3D"=
color:#000"> collapse</span><span style=3D"color:#660">&lt;</span><span sty=
le=3D"color:#000">T</span><span style=3D"color:#660">&gt;::</span><span sty=
le=3D"color:#000">type</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br><br></span><span style=3D"color:#008">template</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#008">class</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">struct</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Helper</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 <=
/span><span style=3D"color:#008">void</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">operator</span><span style=3D"color:#660">()=
(</span><span style=3D"color:#000">collapse_t</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660"=
>)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 bar</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#000">forward</span><span style=3D"co=
lor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"colo=
r:#660">&gt;(</span><span style=3D"color:#000">t</span><span style=3D"color=
:#660">));</span><span style=3D"color:#000"> </span><span style=3D"color:#8=
00">// What do you do here?</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span>=
<span style=3D"color:#008">template</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</s=
pan><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#008">void</s=
pan><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;&amp;<=
/span><span style=3D"color:#000"> t</span><span style=3D"color:#660">)</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#606">Helper=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</=
span><span style=3D"color:#660">&gt;{}(</span><span style=3D"color:#000">st=
d</span><span style=3D"color:#660">::</span><span style=3D"color:#000">forw=
ard</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">=
T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">t=
</span><span style=3D"color:#660">)<wbr>);</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><=
/span><br></div></code></div></div><div>=C2=A0</div></div></blockquote><div=
><br></div><div><br></div><div>In this case you are forwarding as a differe=
nt type. This is the reason std::forward will not be deprecated.=C2=A0</div=
><div>And as a nice side effect - we can finally explain to a beginner why =
does forward need a template argument - to be able to forward as different =
type! (a cop out, =E2=80=A6 or may be not)</div></div></blockquote><div><br=
></div><div>In that example, I&#39;m not forwarding as a different type. As=
 far as the compiler is concerned, I might be, but actually I&#39;m not.<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 d=
ir=3D"ltr"><div><br></div><div><br></div><div>=C2=A0</div><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>In this example, you have no a=
ctual reference collapsing. And you cannot implement it with reference coll=
apsing only, as you need the specialization for pointers.</div><div>This is=
 the kind of code I&#39;m worried about with your operator.</div><div>And i=
t should work the same if, for whatever reason I change it back to some sim=
pler implementation using reference collapsing.</div><div>Reference collaps=
ing is transparent!<br></div><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><span style=3D"display:inline!important;floa=
t:none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norma=
l;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:left=
;text-decoration:none;text-indent:0px;text-transform:none;white-space:norma=
l;word-spacing:0px"><span style=3D"display:inline!important;float:none;back=
ground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,=
&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-vari=
ant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decor=
ation:none;text-indent:0px;text-transform:none;white-space:normal;word-spac=
ing:0px"><br></span></span></div><div><span style=3D"display:inline!importa=
nt;float:none;background-color:transparent;color:rgb(34,34,34);font-family:=
&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-styl=
e:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-ali=
gn:left;text-decoration:none;text-indent:0px;text-transform:none;white-spac=
e:normal;word-spacing:0px"><span style=3D"display:inline!important;float:no=
ne;background-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial=
&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;fo=
nt-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;tex=
t-decoration:none;text-indent:0px;text-transform:none;white-space:normal;wo=
rd-spacing:0px">In a forwarding ref case the compiler will always use &#39;=
give&#39; (as was in the example!), <i>not matter what the forwarding refer=
ence collapses to!</i></span></span></div></div></blockquote><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div><span style=3D"display:inli=
ne!important;float:none;background-color:transparent;color:rgb(34,34,34);fo=
nt-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px=
;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:norma=
l;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;=
white-space:normal;word-spacing:0px"><span style=3D"display:inline!importan=
t;float:none;background-color:transparent;color:rgb(34,34,34);font-family:&=
quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style=
:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text-alig=
n:left;text-decoration:none;text-indent:0px;text-transform:none;white-space=
:normal;word-spacing:0px"><i></i><i></i><i></i><br></span></span></div><div=
><span style=3D"display:inline!important;float:none;background-color:transp=
arent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-wei=
ght:400;letter-spacing:normal;text-align:left;text-decoration:none;text-ind=
ent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span styl=
e=3D"display:inline!important;float:none;background-color:transparent;color=
:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;let=
ter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;tex=
t-transform:none;white-space:normal;word-spacing:0px">The compiler will onl=
y EVER use &#39;giveref&#39; to cast a real lvalue (T&amp;&amp; is not an l=
value anyway)</span></span></div></div></blockquote><div><br></div><div>T&a=
mp;&amp; might be an lvalue reference.<br></div></div></blockquote><div><br=
></div><div>As per definition it is &quot;rvalue reference to a cv-unqualif=
ied template parameter&quot;.=C2=A0</div><div>Yeah, given <font face=3D"cou=
rier new,monospace">T&amp;&amp; x, decltype(x)</font> might be <font face=
=3D"courier new,monospace">const &amp;</font>, but that is after collapsing=
..=C2=A0</div></div></blockquote><div><br></div><div>Here you&#39;re mixing =
the type declaration and the actual type.</div><div>A type declaration cann=
ot be a &quot;rvalue reference&quot;, it might declare a rvalue reference t=
hough.<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><div>As said the compiler will always st=
atic_cast&lt;T&amp;&amp;&gt; when he sees T&amp;&amp;, =E2=80=A6 or any &am=
p;&amp; for that matter, =E2=80=A6 and even if no reference is present.=C2=
=A0</div><div><br></div><div>The compiler will need to remove_reference onl=
y in the case of casting real lvalue reference to rvalue.=C2=A0</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><=
/div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div><span style=3D"display:inline!important;float:none;background-colo=
r:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helve=
tica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;=
font-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;=
text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><s=
pan style=3D"display:inline!important;float:none;background-color:transpare=
nt;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,=
sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight=
:400;letter-spacing:normal;text-align:left;text-decoration:none;text-indent=
:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></span></=
span></div><div><span style=3D"display:inline!important;float:none;backgrou=
nd-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quo=
t;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:=
normal;font-weight:400;letter-spacing:normal;text-align:left;text-decoratio=
n:none;text-indent:0px;text-transform:none;white-space:normal;word-spacing:=
0px"><span style=3D"display:inline!important;float:none;background-color:tr=
ansparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica=
&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font=
-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">I beli=
eve this will work <i>all the time</i>, given current prerequisites - to be=
 <i>as-if</i> move or forward is used correctly.=C2=A0</span></span></div><=
div><span style=3D"display:inline!important;float:none;background-color:tra=
nsparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font-=
weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text-=
indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span s=
tyle=3D"display:inline!important;float:none;background-color:transparent;co=
lor:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-=
serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;=
letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;=
text-transform:none;white-space:normal;word-spacing:0px"><br></span></span>=
</div></div></blockquote><div><br></div><div>See my example above.<br></div=
><div>=C2=A0</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><span style=3D"display:inline!important;float:none;background-color:tr=
ansparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica=
&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;font=
-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;text=
-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span =
style=3D"display:inline!important;float:none;background-color:transparent;c=
olor:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans=
-serif;font-size:13px;font-style:normal;font-variant:normal;font-weight:400=
;letter-spacing:normal;text-align:left;text-decoration:none;text-indent:0px=
;text-transform:none;white-space:normal;word-spacing:0px"></span></span></d=
iv><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div><br></div><div>But if the identifier is not a reference, then moving=
 is the correct thing to do. Actually, that&#39;s the current rule for <spa=
n style=3D"font-family:courier new,monospace">std::forward</span>:</div><di=
v><span style=3D"font-family:courier new,monospace">...</span><code><span s=
tyle=3D"color:#000"><br></span></code></div><div>It doesn&#39;t matter if <=
span style=3D"font-family:courier new,monospace">i</span>, <span style=3D"f=
ont-family:courier new,monospace">j</span> or <span style=3D"font-family:co=
urier new,monospace">k</span> are local variables, function parameters, or =
even result of functions: the result is the same.</div><div><br></div><div>=
If you really want to move <span style=3D"font-family:courier new,monospace=
">j</span> in that case, I would say calling <span style=3D"font-family:cou=
rier new,monospace">std::move(j)</span> explicitely is fine: this is clearl=
y not used very often, but should still be possible to do.</div><div><br></=
div><div>In short, use <span style=3D"font-family:courier new,monospace">&a=
mp;&amp;&gt;</span> when you want to give a variable/expression away.</div>=
<div>And use <span style=3D"font-family:courier new,monospace">std::move</s=
pan> if you always want move. (no change required to <span style=3D"font-fa=
mily:courier new,monospace">std::move</span>)</div><div>Those are very cons=
istent rules that can be applied blindly, and don&#39;t depend on the conte=
xt (template code or regular code).</div><div>It only depends on the progra=
mmer intent. And that&#39;s what we want. (At least, that&#39;s what I want=
)<br></div></div></blockquote><div><br></div><div><br></div><div>If we have=
 to use both &amp;&amp;&gt; and move, we are back to where we stared - lear=
n when to use what. forward vs move is now &amp;&amp;&gt; vs move=C2=A0</di=
v></div></blockquote><div><br></div><div>This is not the same. &amp;&amp;&g=
t; and std::move are not for the same purpose:</div><div>&amp;&amp;&gt;: I =
don&#39;t use this object anymore.</div><div>std::move(): nobody uses this =
object anymore (I promise), so the callee can do anything they want with it=
..</div></div></blockquote><div><br></div><div><br></div><div>You have a poi=
nt.=C2=A0</div><div>And I really do appreciate this alternative views.=C2=
=A0</div><div>I for example initially considered proposing to forbid moving=
 from const &amp; (fails to compile) because it is confusing and a code-lie=
..</div><div>I also considered move to be always move_if_noexcept instead.</=
div></div></blockquote><div><br></div><div>Your operator should not fail to=
 compile. If there are cases where it does, then it is completely useless f=
or templates<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><br></div><div>But I deliberately dropped AL=
L &quot;new ideas&quot; and focused on &quot;pure wins&quot; in the form &q=
uot;better ways to do the old stuff&quot; - move and forward under one no-d=
ecision syntax.=C2=A0<br></div><div>(Now that I think about it I haven&#39;=
t completely dropped <span style=3D"display:inline!important;float:none;bac=
kground-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;=
,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-var=
iant:normal;font-weight:400;letter-spacing:normal;text-align:left;text-deco=
ration:none;text-indent:0px;text-transform:none;white-space:normal;word-spa=
cing:0px">move_if_noexcept, but I have not studied it</span>)</div><div><br=
></div><div><br></div><div>Besides, given</div><div><br></div><div><font fa=
ce=3D"courier new,monospace">auto&amp; a =3D geta();</font></div><div><font=
 face=3D"courier new,monospace"><br></font></div><div>These two would be eq=
uivalent.=C2=A0</div><div><br></div><div><font face=3D"courier new,monospac=
e">oms(a&amp;&amp;&gt;);</font></div><div><font face=3D"courier new,monospa=
ce">oms(a);=C2=A0</font></div></div></blockquote><div><br></div><div>Here, =
he is being explicit that he doesn&#39;t use <span style=3D"font-family: co=
urier new, monospace;">a</span> after <span style=3D"font-family: courier n=
ew, monospace;">a&amp;&amp;&gt;</span> (despite doing it anyway, but I&#39;=
m pretty sure you put the second line just for comparison).</div><div>But t=
he function that returned the reference in the first place might need the o=
bject in the future. So it shouldn&#39;t be implicitly moved. That would be=
 dangerous.<br></div><div><br></div><div>However:</div><div><div style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pr=
ettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span =
style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> a </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> geta</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> b </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> getb=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>oms</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// will use it afterwards</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>oms</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">a</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&amp;&amp;&gt;);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// will not use it afterwards</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>oms</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">b</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&amp;&amp;&gt;);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//will not use it afterwards</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span></div></code></div></div><div>If <=
span style=3D"font-family: courier new, monospace;">a</span> is a rvalue re=
ference, <span style=3D"font-family: courier new, monospace;">a&amp;&amp;&g=
t;</span> will correctly move it.</div><div>If <span style=3D"font-family: =
courier new, monospace;">a</span> happens to be a lvalue reference, it will=
 not be moved, but just forwarded as is.</div><div>As <span style=3D"font-f=
amily: courier new, monospace;">b</span> cannot be a reference (that&#39;s =
how auto works), <span style=3D"font-family: courier new, monospace;">b</sp=
an> will be moved: there is no outside world.<br></div><div><br></div><div>=
Now:</div><div><div style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; overflow-=
wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> a </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> geta</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br><br>oms</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">move</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-prettif=
y">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span></div></code></div>Will move <span style=3D"font-family: courier new=
, monospace;">a</span> even if <span style=3D"font-family: courier new, mon=
ospace;">a</span> is an lvalue reference, even if the object was still need=
ed somewhere else (so to be used with caution).<br><br></div><div>=C2=A0</d=
iv><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><font=
 face=3D"courier new,monospace"><br></font></div><div><font face=3D"arial,s=
ans-serif">This is bad, the user is explicit he what it moved, if he does n=
ot, he would have used the second syntax.</font></div><div><font face=3D"ar=
ial,sans-serif"><br></font></div><div><font face=3D"arial,sans-serif">What =
are the options? Make it fail to compile, so the user must use std::move.=
=C2=A0</font></div></div></blockquote><div><br></div><div>Don&#39;t make it=
 fail, it would defeat the whole purpose.<br></div><div>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><font face=3D"a=
rial,sans-serif">Ok, but than the user will be just as annoyed he has to us=
e some different syntax so that he achieve the same thing in the end.</font=
></div><div><font face=3D"arial,sans-serif">After all <i>he is already expl=
icit</i>, being <i>also</i> explicit <i>in a special way, </i>and <i>in a s=
pecial case</i> can bit too much and my objective is streamlining.=C2=A0</f=
ont></div></div></blockquote><div><br></div><div>He is being explicit about=
 his code, not about the rest of the world. While with <span style=3D"font-=
family: courier new, monospace;">std::move()</span> he would be explicit ab=
out the whole world.</div><div>If he owns the object, his code is the whole=
 world (as far as the object is concerned), so that&#39;s fine.</div><div><=
br></div><div>If you consider the amount of code using <span style=3D"font-=
family: courier new, monospace;">std::forward</span> and the amount of code=
 using <span style=3D"font-family: courier new, monospace;">std::move</span=
> on lvalue references (not local objects), it is pretty clear who the winn=
er is.<br></div><div>=C2=A0</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/41662b6a-f5ce-4d03-a436-d43a75c4d3ab%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/41662b6a-f5ce-4d03-a436-d43a75c4d3ab=
%40isocpp.org</a>.<br />

------=_Part_56692_1136362514.1528651034596--

------=_Part_56691_2004630572.1528651034595--

.


Author: mihailnajdenov@gmail.com
Date: Sun, 10 Jun 2018 11:59:45 -0700 (PDT)
Raw View
------=_Part_89874_1151616353.1528657185129
Content-Type: multipart/alternative;
 boundary="----=_Part_89875_1505753424.1528657185130"

------=_Part_89875_1505753424.1528657185130
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>
>>
>>
>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com wrote:
>>>
>>>
>>>
>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9c=
rit :
>>>>
>>>>
>>>>
>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=20
>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>> =C3=A9crit :...
>>>>>
>>>>
>>> But you can always imagine some meta-function that give the same result=
=20
>>> as reference collapsing without relying on reference collapsing, and th=
at=20
>>> being used as a function parameter.
>>> Reference collapsing is a bit like "forwarding" reference: once it has=
=20
>>> happened, it should behave the same as if never happened in the first p=
lace=20
>>> if the types are equals.
>>>
>>> template <class T> struct collapse      { using type =3D T&&; };
>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
>>> Optimization for trivial types=20
>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>
>>>
>>> template <class T>
>>> struct Helper {
>>>   void operator()(collapse_t<T> t) {
>>>     bar(std::forward<T>(t)); // What do you do here?
>>> };
>>>
>>> template <class T>
>>> void foo(T&& t) {
>>>   Helper<T>{}(std::forward<T>(t));
>>> }
>>> =20
>>>
>>
>>
>> In this case you are forwarding as a different type. This is the reason=
=20
>> std::forward will not be deprecated.=20
>> And as a nice side effect - we can finally explain to a beginner why doe=
s=20
>> forward need a template argument - to be able to forward as different ty=
pe!=20
>> (a cop out, =E2=80=A6 or may be not)
>>
>
> In that example, I'm not forwarding as a different type. As far as the=20
> compiler is concerned, I might be, but actually I'm not.
>

You are building your own type-system. You are forwarding A<B> as B.=20

I guess it can be done, we can imagine some interface like begin() end()=20
for for or get() for structure binding, but these are out of scope.

You can share your concrete needs, might add Future Direction section or=20
something.=20
For now I care about to have language level tools to have "zero overhead"=
=20
language level syntax to use them.

=20
>
>>
>>
>>  =E2=80=A6...
>>
>
>>
>> Besides, given
>>
>> auto& a =3D geta();
>>
>> These two would be equivalent.=20
>>
>> oms(a&&>);
>> oms(a);=20
>>
>
> Here, he is being explicit that he doesn't use a after a&&> (despite=20
> doing it anyway, but I'm pretty sure you put the second line just for=20
> comparison).
> But the function that returned the reference in the first place might nee=
d=20
> the object in the future. So it shouldn't be implicitly moved. That would=
=20
> be dangerous.
>
> However:
> auto&& a =3D geta();
> auto b =3D getb();
>
> oms(a); // will use it afterwards
> oms(a&&>); // will not use it afterwards
> oms(b&&>); //will not use it afterwards
> If a is a rvalue reference, a&&> will correctly move it.
> If a happens to be a lvalue reference, it will not be moved, but just=20
> forwarded as is.
>


 At the moment &&> will behave EXACTLY as you described.=20


=20

> As b cannot be a reference (that's how auto works), b will be moved:=20
> there is no outside world.
>
> Now:
> auto&& a =3D geta();
>
> oms(std::move(a));
> Will move a even if a is an lvalue reference, even if the object was=20
> still needed somewhere else (so to be used with caution).
>


And this is EXACTLY why move will not be deprecated - to force-cast a=20
collapsing reference.=20


I am a bit confused.=20
I think you think about auto&& to be the type of decltype(a), but I think=
=20
of it as collapsing reference because at it is at that point,=20
when it is still a collapsing reference, that the compiler will inject the=
=20
correct impl of give. After collapse is way too late, of course.=20

=20

>
> =20
>
>>
>> This is bad, the user is explicit he what it moved, if he does not, he=
=20
>> would have used the second syntax.
>>
>> What are the options? Make it fail to compile, so the user must use=20
>> std::move.=20
>>
>
> Don't make it fail, it would defeat the whole purpose.
> =20
>
>> Ok, but than the user will be just as annoyed he has to use some=20
>> different syntax so that he achieve the same thing in the end.
>> After all *he is already explicit*, being *also* explicit *in a special=
=20
>> way, *and *in a special case* can bit too much and my objective is=20
>> streamlining.=20
>>
>
> He is being explicit about his code, not about the rest of the world.=20
> While with std::move() he would be explicit about the whole world.
> If he owns the object, his code is the whole world (as far as the object=
=20
> is concerned), so that's fine.
>
> If you consider the amount of code using std::forward and the amount of=
=20
> code using std::move on lvalue references (not local objects), it is=20
> pretty clear who the winner is.
> =20
>

--=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/1433d64f-a9da-4581-9abe-c3aaaec8cb88%40isocpp.or=
g.

------=_Part_89875_1505753424.1528657185130
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, flor=
ia...@gmail.com 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"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.=
com</a> 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"><div dir=
=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...=
@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com=
</a> a =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div><br><=
/div><div>But you can always imagine some meta-function that give the same =
result as reference collapsing without relying on reference collapsing, and=
 that being used as a function parameter.</div><div>Reference collapsing is=
 a bit like &quot;forwarding&quot; reference: once it has happened, it shou=
ld behave the same as if never happened in the first place if the types are=
 equals.</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#008">template</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008=
">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">using</span><span style=3D"color:#000"> type </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> collapse</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&=
amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">using</sp=
an><span style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> collapse</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> ty=
pe </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
><code><span style=3D"color:#000"><br></span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">* &gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">using</span><span style=3D"color:#000">=
 type </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
></span></code></span><span style=3D"color:#000"><code><span style=3D"color=
:#000"><code><span style=3D"color:#800"> // Optimization for trivial types =
</span><span style=3D"color:#000"><br></span></code></span></code></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">using</span>=
<span style=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>typename</span><span style=3D"color:#000"> collapse</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"col=
or:#660">&gt;::</span><span style=3D"color:#000">type</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br><br><br></span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</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">struct</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Helper</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">operator</spa=
n><span style=3D"color:#660">()(</span><span style=3D"color:#000">collapse_=
t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> t</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 bar</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">forward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#=
000">t</span><span style=3D"color:#660">));</span><span style=3D"color:#000=
"> </span><span style=3D"color:#800">// What do you do here?</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span sty=
le=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><s=
pan 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:#660">(</span><span style=3D"color:#000">T</span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span>=
<span style=3D"color:#606">Helper</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</=
span><span style=3D"color:#000">t</span><span style=3D"color:#660">)<wbr>);=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"></span><br></div></code></div></div><div>=
=C2=A0</div></div></blockquote><div><br></div><div><br></div><div>In this c=
ase you are forwarding as a different type. This is the reason std::forward=
 will not be deprecated.=C2=A0</div><div>And as a nice side effect - we can=
 finally explain to a beginner why does forward need a template argument - =
to be able to forward as different type! (a cop out, =E2=80=A6 or may be no=
t)</div></div></blockquote><div><br></div><div>In that example, I&#39;m not=
 forwarding as a different type. As far as the compiler is concerned, I mig=
ht be, but actually I&#39;m not.<br></div></div></blockquote><div><br></div=
><div>You are building your own type-system. <span style=3D"display: inline=
 !important; float: none; background-color: transparent; color: rgb(34, 34,=
 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">You are forwarding A&lt;B&gt; as B.=
=C2=A0</span><br></div><div><br></div><div>I guess it can be done, we can i=
magine some interface like begin() end() for for or get() for structure bin=
ding, but these are out of scope.</div><div><br></div><div>You can share yo=
ur concrete needs, might add Future Direction section or something.=C2=A0</=
div><div>For now I care about to have language level tools to have &quot;ze=
ro overhead&quot; language level syntax to use them.</div><div><br></div><b=
lockquote 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></div><div=
>=C2=A0</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>=
<br></div><div><br></div><div>=C2=A0=E2=80=A6...</div></div></blockquote><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"><div><br></div><div>=
<br></div><div>Besides, given</div><div><br></div><div><font face=3D"courie=
r new,monospace">auto&amp; a =3D geta();</font></div><div><font face=3D"cou=
rier new,monospace"><br></font></div><div>These two would be equivalent.=C2=
=A0</div><div><br></div><div><font face=3D"courier new,monospace">oms(a&amp=
;&amp;&gt;);</font></div><div><font face=3D"courier new,monospace">oms(a);=
=C2=A0</font></div></div></blockquote><div><br></div><div>Here, he is being=
 explicit that he doesn&#39;t use <span style=3D"font-family:courier new,mo=
nospace">a</span> after <span style=3D"font-family:courier new,monospace">a=
&amp;&amp;&gt;</span> (despite doing it anyway, but I&#39;m pretty sure you=
 put the second line just for comparison).</div><div>But the function that =
returned the reference in the first place might need the object in the futu=
re. So it shouldn&#39;t be implicitly moved. That would be dangerous.<br></=
div><div><br></div><div>However:</div><div><div style=3D"background-color:r=
gb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wid=
th:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"col=
or:#660">&amp;&amp;</span><span style=3D"color:#000"> a </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> geta</span><span styl=
e=3D"color:#660">();</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#008">auto</span><span style=3D"color:#000"> b </span><span styl=
e=3D"color:#660">=3D</span><span style=3D"color:#000"> getb</span><span sty=
le=3D"color:#660">();</span><span style=3D"color:#000"><br><br>oms</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">a</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">// will use it afterwards</span><span style=3D"color:#000">=
<br>oms</span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>a</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#800">// will not use it afterwards=
</span><span style=3D"color:#000"><br>oms</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">b</span><span style=3D"color:#660">&amp;=
&amp;&gt;);</span><span style=3D"color:#000"> </span><span style=3D"color:#=
800">//will not use it afterwards</span><span style=3D"color:#000"><br></sp=
an></div></code></div></div><div>If <span style=3D"font-family:courier new,=
monospace">a</span> is a rvalue reference, <span style=3D"font-family:couri=
er new,monospace">a&amp;&amp;&gt;</span> will correctly move it.</div><div>=
If <span style=3D"font-family:courier new,monospace">a</span> happens to be=
 a lvalue reference, it will not be moved, but just forwarded as is.</div><=
/div></blockquote><div><br></div><div><br></div><div>=C2=A0At the moment &a=
mp;&amp;&gt; will behave EXACTLY as you described.=C2=A0</div><div><br></di=
v><div><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>As <span style=3D"font-family:courier new,monos=
pace">b</span> cannot be a reference (that&#39;s how auto works), <span sty=
le=3D"font-family:courier new,monospace">b</span> will be moved: there is n=
o outside world.<br></div><div><br></div><div>Now:</div><div><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px"><code><div><span style=3D"color:#008">auto</span>=
<span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> a <=
/span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> geta=
</span><span style=3D"color:#660">();</span><span style=3D"color:#000"><br>=
<br>oms</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">m=
ove</span><span style=3D"color:#660">(</span><span style=3D"color:#000">a</=
span><span style=3D"color:#660">));</span><span style=3D"color:#000"><br></=
span></div></code></div>Will move <span style=3D"font-family:courier new,mo=
nospace">a</span> even if <span style=3D"font-family:courier new,monospace"=
>a</span> is an lvalue reference, even if the object was still needed somew=
here else (so to be used with caution).<br></div></div></blockquote><div><b=
r></div><div><br></div><div>And this is EXACTLY why move will not be deprec=
ated - to force-cast a collapsing reference.=C2=A0</div><div><br></div><div=
><br></div><div>I am a bit confused.=C2=A0</div><div>I think you think abou=
t <font face=3D"courier new,monospace">auto&amp;&amp;</font> to be the type=
 of <font face=3D"courier new,monospace">decltype(a), <font face=3D"arial,s=
ans-serif">but I think of it as collapsing reference because at it is at th=
at point,=C2=A0</font></font></div><div><font face=3D"courier new,monospace=
"><font face=3D"arial,sans-serif">when it is still a collapsing reference, =
that the compiler will inject the correct impl of give. After collapse is w=
ay too late, of course.=C2=A0</font></font></div><div><font face=3D"courier=
 new,monospace"></font><br></div><div>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>=C2=A0</div><block=
quote 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><font face=3D"couri=
er new,monospace"><br></font></div><div><font face=3D"arial,sans-serif">Thi=
s is bad, the user is explicit he what it moved, if he does not, he would h=
ave used the second syntax.</font></div><div><font face=3D"arial,sans-serif=
"><br></font></div><div><font face=3D"arial,sans-serif">What are the option=
s? Make it fail to compile, so the user must use std::move.=C2=A0</font></d=
iv></div></blockquote><div><br></div><div>Don&#39;t make it fail, it would =
defeat the whole purpose.<br></div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div><font face=3D"arial,sans-serif">Ok, =
but than the user will be just as annoyed he has to use some different synt=
ax so that he achieve the same thing in the end.</font></div><div><font fac=
e=3D"arial,sans-serif">After all <i>he is already explicit</i>, being <i>al=
so</i> explicit <i>in a special way, </i>and <i>in a special case</i> can b=
it too much and my objective is streamlining.=C2=A0</font></div></div></blo=
ckquote><div><br></div><div>He is being explicit about his code, not about =
the rest of the world. While with <span style=3D"font-family:courier new,mo=
nospace">std::move()</span> he would be explicit about the whole world.</di=
v><div>If he owns the object, his code is the whole world (as far as the ob=
ject is concerned), so that&#39;s fine.</div><div><br></div><div>If you con=
sider the amount of code using <span style=3D"font-family:courier new,monos=
pace">std::forward</span> and the amount of code using <span style=3D"font-=
family:courier new,monospace">std::move</span> on lvalue references (not lo=
cal objects), it is pretty clear who the winner is.<br></div><div>=C2=A0</d=
iv></div></blockquote></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/1433d64f-a9da-4581-9abe-c3aaaec8cb88%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1433d64f-a9da-4581-9abe-c3aaaec8cb88=
%40isocpp.org</a>.<br />

------=_Part_89875_1505753424.1528657185130--

------=_Part_89874_1151616353.1528657185129--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 10 Jun 2018 12:22:07 -0700 (PDT)
Raw View
------=_Part_90545_2088580460.1528658527328
Content-Type: multipart/alternative;
 boundary="----=_Part_90546_264535059.1528658527328"

------=_Part_90546_264535059.1528658527328
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sunday, June 10, 2018 at 2:59:45 PM UTC-4, mihailn...@gmail.com wrote:
>
>
>
> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>>
>>>
>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com wrote=
:
>>>>
>>>>
>>>>
>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9=
crit :
>>>>>
>>>>>
>>>>>
>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=20
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>>> =C3=A9crit :...
>>>>>>
>>>>>
>>>> But you can always imagine some meta-function that give the same resul=
t=20
>>>> as reference collapsing without relying on reference collapsing, and t=
hat=20
>>>> being used as a function parameter.
>>>> Reference collapsing is a bit like "forwarding" reference: once it has=
=20
>>>> happened, it should behave the same as if never happened in the first =
place=20
>>>> if the types are equals.
>>>>
>>>> template <class T> struct collapse      { using type =3D T&&; };
>>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
>>>> Optimization for trivial types=20
>>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>>
>>>>
>>>> template <class T>
>>>> struct Helper {
>>>>   void operator()(collapse_t<T> t) {
>>>>     bar(std::forward<T>(t)); // What do you do here?
>>>> };
>>>>
>>>> template <class T>
>>>> void foo(T&& t) {
>>>>   Helper<T>{}(std::forward<T>(t));
>>>> }
>>>> =20
>>>>
>>>
>>>
>>> In this case you are forwarding as a different type. This is the reason=
=20
>>> std::forward will not be deprecated.=20
>>> And as a nice side effect - we can finally explain to a beginner why=20
>>> does forward need a template argument - to be able to forward as differ=
ent=20
>>> type! (a cop out, =E2=80=A6 or may be not)
>>>
>>
>> In that example, I'm not forwarding as a different type. As far as the=
=20
>> compiler is concerned, I might be, but actually I'm not.
>>
>
> You are building your own type-system. You are forwarding A<B> as B.
>

Incorrect. `collapse_t` is an *alias* for a type. In this case,=20
`collapse_t<T>` is an alias for `T` with some form of reference. So it's=20
not some other type.

--=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/76449b90-6455-4e7f-9de8-ba11871a05a5%40isocpp.or=
g.

------=_Part_90546_264535059.1528658527328
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, June 10, 2018 at 2:59:45 PM UTC-4, mihailn...@g=
mail.com 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=
"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>floria...@gmail.=
com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>=
<br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gmail.com</a> a =
=C3=A9crit=C2=A0:<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"><=
br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <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"><br><br=
>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.com</a> a =C3=
=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br>=
<br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...@gmail.com</a=
> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>Le=
 dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com</a> a =C3=A9=
crit=C2=A0:...</div></blockquote></div></blockquote><div><br></div><div>But=
 you can always imagine some meta-function that give the same result as ref=
erence collapsing without relying on reference collapsing, and that being u=
sed as a function parameter.</div><div>Reference collapsing is a bit like &=
quot;forwarding&quot; reference: once it has happened, it should behave the=
 same as if never happened in the first place if the types are equals.</div=
><div><br></div><div><div style=3D"background-color:rgb(250,250,250);border=
-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><sp=
an style=3D"color:#008">template</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span=
><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">struct</span>=
<span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">using</span><span style=3D"color:#000"> type </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><sp=
an style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">struct</span><spa=
n style=3D"color:#000"> collapse</span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#000">T</span><span style=3D"color:#660">&amp;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&gt;</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">using</span><span s=
tyle=3D"color:#000"> type </span><span style=3D"color:#660">=3D</span><span=
 style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">};</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">template</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">struct</span><span style=3D"color:#000"> collapse</span><sp=
an style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span=
 style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">using</span><span style=3D"color:#000"> type </spa=
n><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span>=
<span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">};</span><span style=3D"color:#000"><code><=
span style=3D"color:#000"><br></span><span style=3D"color:#008">template</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</spa=
n><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</spa=
n><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">struct</span><span style=3D"color:#000"> collaps=
e</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T<=
/span><span style=3D"color:#660">* &gt;</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">using</span><span style=3D"color:#000"> type </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</sp=
an><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">};</span><span style=3D"color:#000"></span>=
</code></span><span style=3D"color:#000"><code><span style=3D"color:#000"><=
code><span style=3D"color:#800"> // Optimization for trivial types </span><=
span style=3D"color:#000"><br></span></code></span></code></span><span styl=
e=3D"color:#008">template</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><span =
style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">using</span><span st=
yle=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"color:#660">=3D<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> collapse</span><span style=3D"color:#66=
0">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660"=
>&gt;::</span><span style=3D"color:#000">type</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"><br><br><br></span><span style=3D"co=
lor:#008">template</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">&lt;</span><span style=3D"color:#008">class</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">struct</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#606">Helper</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">operator</span><=
span style=3D"color:#660">()(</span><span style=3D"color:#000">collapse_t</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> t</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 bar</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">f=
orward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#00=
0">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000=
">t</span><span style=3D"color:#660">));</span><span style=3D"color:#000"> =
</span><span style=3D"color:#800">// What do you do here?</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><spa=
n style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">T</span><span s=
tyle=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t</span><s=
pan style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><s=
pan style=3D"color:#606">Helper</span><span style=3D"color:#660">&lt;</span=
><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</spa=
n><span style=3D"color:#000">std</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</sp=
an><span style=3D"color:#000">t</span><span style=3D"color:#660">)<wbr>);</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</sp=
an><span style=3D"color:#000"></span><br></div></code></div></div><div>=C2=
=A0</div></div></blockquote><div><br></div><div><br></div><div>In this case=
 you are forwarding as a different type. This is the reason std::forward wi=
ll not be deprecated.=C2=A0</div><div>And as a nice side effect - we can fi=
nally explain to a beginner why does forward need a template argument - to =
be able to forward as different type! (a cop out, =E2=80=A6 or may be not)<=
/div></div></blockquote><div><br></div><div>In that example, I&#39;m not fo=
rwarding as a different type. As far as the compiler is concerned, I might =
be, but actually I&#39;m not.<br></div></div></blockquote><div><br></div><d=
iv>You are building your own type-system. <span style=3D"display:inline!imp=
ortant;float:none;background-color:transparent;color:rgb(34,34,34);font-fam=
ily:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-=
style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;text=
-align:left;text-decoration:none;text-indent:0px;text-transform:none;white-=
space:normal;word-spacing:0px">You are forwarding A&lt;B&gt; as B.</span></=
div></div></blockquote><div><br></div><div>Incorrect. `collapse_t` is an <i=
>alias</i> for a type. In this case, `collapse_t&lt;T&gt;` is an alias for =
`T` with some form of reference. So it&#39;s not some other type.<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/76449b90-6455-4e7f-9de8-ba11871a05a5%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/76449b90-6455-4e7f-9de8-ba11871a05a5=
%40isocpp.org</a>.<br />

------=_Part_90546_264535059.1528658527328--

------=_Part_90545_2088580460.1528658527328--

.


Author: florian.csdt@gmail.com
Date: Sun, 10 Jun 2018 12:25:01 -0700 (PDT)
Raw View
------=_Part_58742_1928786916.1528658701612
Content-Type: multipart/alternative;
 boundary="----=_Part_58743_1976514343.1528658701614"

------=_Part_58743_1976514343.1528658701614
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn...@gmail.com a =C3=A9crit =
:
>
>
>
> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>>
>>>
>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com wrote=
:
>>>>
>>>>
>>>>
>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a =C3=A9=
crit :
>>>>>
>>>>>
>>>>>
>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=20
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>>> =C3=A9crit :...
>>>>>>
>>>>>
>>>> But you can always imagine some meta-function that give the same resul=
t=20
>>>> as reference collapsing without relying on reference collapsing, and t=
hat=20
>>>> being used as a function parameter.
>>>> Reference collapsing is a bit like "forwarding" reference: once it has=
=20
>>>> happened, it should behave the same as if never happened in the first =
place=20
>>>> if the types are equals.
>>>>
>>>> template <class T> struct collapse      { using type =3D T&&; };
>>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=20
>>>> Optimization for trivial types=20
>>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>>
>>>>
>>>> template <class T>
>>>> struct Helper {
>>>>   void operator()(collapse_t<T> t) {
>>>>     bar(std::forward<T>(t)); // What do you do here?
>>>> };
>>>>
>>>> template <class T>
>>>> void foo(T&& t) {
>>>>   Helper<T>{}(std::forward<T>(t));
>>>> }
>>>> =20
>>>>
>>>
>>>
>>> In this case you are forwarding as a different type. This is the reason=
=20
>>> std::forward will not be deprecated.=20
>>> And as a nice side effect - we can finally explain to a beginner why=20
>>> does forward need a template argument - to be able to forward as differ=
ent=20
>>> type! (a cop out, =E2=80=A6 or may be not)
>>>
>>
>> In that example, I'm not forwarding as a different type. As far as the=
=20
>> compiler is concerned, I might be, but actually I'm not.
>>
>
> You are building your own type-system. You are forwarding A<B> as B.=20
>
> I guess it can be done, we can imagine some interface like begin() end()=
=20
> for for or get() for structure binding, but these are out of scope.
>

What I wanted to say: it is currently possible to write that kind of, it=20
should still be possible with what you propose.
I don't want such a collapse_t to be in the standard at all. But it is=20
possible to write it and use it.
And to some extent (not this particular example), it is used.
=20

>
> You can share your concrete needs, might add Future Direction section or=
=20
> something.=20
> For now I care about to have language level tools to have "zero overhead"=
=20
> language level syntax to use them.
>
>
Agreed.
=20

> =20
>>
>>>
>>>
>>>  =E2=80=A6...
>>>
>>
>>>
>>> Besides, given
>>>
>>> auto& a =3D geta();
>>>
>>> These two would be equivalent.=20
>>>
>>> oms(a&&>);
>>> oms(a);=20
>>>
>>
>> Here, he is being explicit that he doesn't use a after a&&> (despite=20
>> doing it anyway, but I'm pretty sure you put the second line just for=20
>> comparison).
>> But the function that returned the reference in the first place might=20
>> need the object in the future. So it shouldn't be implicitly moved. That=
=20
>> would be dangerous.
>>
>> However:
>> auto&& a =3D geta();
>> auto b =3D getb();
>>
>> oms(a); // will use it afterwards
>> oms(a&&>); // will not use it afterwards
>> oms(b&&>); //will not use it afterwards
>> If a is a rvalue reference, a&&> will correctly move it.
>> If a happens to be a lvalue reference, it will not be moved, but just=20
>> forwarded as is.
>>
>
>
>  At the moment &&> will behave EXACTLY as you described.=20
>
>
Exactly in those cases, not in the auto& case. I just wanted to highlight=
=20
the differences in those cases.
=20

>
> =20
>
>> As b cannot be a reference (that's how auto works), b will be moved:=20
>> there is no outside world.
>>
>> Now:
>> auto&& a =3D geta();
>>
>> oms(std::move(a));
>> Will move a even if a is an lvalue reference, even if the object was=20
>> still needed somewhere else (so to be used with caution).
>>
>
>
> And this is EXACTLY why move will not be deprecated - to force-cast a=20
> collapsing reference.=20
>
>
> I am a bit confused.=20
> I think you think about auto&& to be the type of decltype(a), but I think=
=20
> of it as collapsing reference because at it is at that point,=20
> when it is still a collapsing reference, that the compiler will inject th=
e=20
> correct impl of give. After collapse is way too late, of course.=20
>

I don't think about auto&& as decltype(a): it is not the same. But this is=
=20
irrelevant to my point.
You want to give a different behavior to auto&& because it collapses=20
references.
That's exactly the point I disagree.
Currently, there is no way to tell when there is reference collapsing. And=
=20
that's perfect because it is a tricky, yet useful, feature of C++.
If you make something behaving differently when there is reference=20
collapsing and where there isn't, the language will get more confusing.

I would expect this:
using A =3D int&;
int i =3D 0;
A&& j =3D i;
foo(j&&>);
to stay equivalent to this:
int i =3D 0;
int &j =3D i;
foo(j&&>);

Because in both cases, j have the exact same type.
With what you propose, they will have different behavior because of the way=
=20
they are declared while being the same type.
And what about:
using A =3D int&;
using B =3D A&&;

int i =3D 0;
B j =3D i;
foo(j&&>); // shall it be moved?


This would be completely new and unusual in the language. This is what I=20
want to avoid.
The type of the variable alone should be enough to decide what to do. (the=
=20
type of the expression is obviously not enough).
All my examples show you what kind of code would behave differently.

Just to clarify things a bit. If I insist, it is because I really want to=
=20
help you finding the problems with your approach (Whatever your approach=20
could be).
While I do prefer my solution, yours is also interesting ;)

--=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/3e258822-7ebf-4de7-9bae-43d280efde09%40isocpp.or=
g.

------=_Part_58743_1976514343.1528658701614
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn..=
..@gmail.com a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>=
floria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@=
gmail.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <a>flo=
ria...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.=
com</a> a =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div><b=
r></div><div>But you can always imagine some meta-function that give the sa=
me result as reference collapsing without relying on reference collapsing, =
and that being used as a function parameter.</div><div>Reference collapsing=
 is a bit like &quot;forwarding&quot; reference: once it has happened, it s=
hould behave the same as if never happened in the first place if the types =
are equals.</div><div><br></div><div><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">template</span><span style=3D"color=
:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
008">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#=
660">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#00=
8">struct</span><span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</=
span><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">using</span><span style=3D"color:#000"> type </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</spa=
n><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#008">template</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">cl=
ass</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">stru=
ct</span><span style=3D"color:#000"> collapse</span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660=
">&amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">using<=
/span><span style=3D"color:#000"> type </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&a=
mp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span=
><span style=3D"color:#000"><br></span><span style=3D"color:#008">template<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</s=
pan><span style=3D"color:#008">class</span><span style=3D"color:#000"> T</s=
pan><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">struct</span><span style=3D"color:#000"> colla=
pse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">=
T</span><span style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#008">using</span><span style=3D"color:#000=
"> type </span><span style=3D"color:#660">=3D</span><span style=3D"color:#0=
00"> T</span><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:=
#000"><code><span style=3D"color:#000"><br></span><span style=3D"color:#008=
">template</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">&lt;</span><span style=3D"color:#008">class</span><span style=3D"color:=
#000"> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">struct</span><span style=3D"color:#=
000"> collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"c=
olor:#000">T</span><span style=3D"color:#660">* &gt;</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:=
#000"> </span><span style=3D"color:#008">using</span><span style=3D"color:#=
000"> type </span><span style=3D"color:#660">=3D</span><span style=3D"color=
:#000"> T</span><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">};</span><span style=3D"color:=
#000"></span></code></span><span style=3D"color:#000"><code><span style=3D"=
color:#000"><code><span style=3D"color:#800"> // Optimization for trivial t=
ypes </span><span style=3D"color:#000"><br></span></code></span></code></sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">using</=
span><span style=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">typename</span><span style=3D"color:#000"> collapse</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#000">T</span><span style=
=3D"color:#660">&gt;::</span><span style=3D"color:#000">type</span><span st=
yle=3D"color:#660">;</span><span style=3D"color:#000"><br><br><br></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><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">struct</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#606">Helper</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><=
span style=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">operat=
or</span><span style=3D"color:#660">()(</span><span style=3D"color:#000">co=
llapse_t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#=
000">T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#00=
0"> t</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 bar</span><span style=3D"color:#660">(</span><span style=3D"c=
olor:#000">std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">forward</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#000">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"=
color:#000">t</span><span style=3D"color:#660">));</span><span style=3D"col=
or:#000"> </span><span style=3D"color:#800">// What do you do here?</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">};</span><s=
pan style=3D"color:#000"><br><br></span><span style=3D"color:#008">template=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</=
span><span style=3D"color:#008">class</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:#660">(</span><span style=3D"color:#000">T</spa=
n><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t=
</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
</span><span style=3D"color:#606">Helper</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt=
;{}(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">forward</span><span style=3D"color:#660=
">&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">=
&gt;(</span><span style=3D"color:#000">t</span><span style=3D"color:#660">)=
<wbr>);</span><span style=3D"color:#000"><br></span><span style=3D"color:#6=
60">}</span><span style=3D"color:#000"></span><br></div></code></div></div>=
<div>=C2=A0</div></div></blockquote><div><br></div><div><br></div><div>In t=
his case you are forwarding as a different type. This is the reason std::fo=
rward will not be deprecated.=C2=A0</div><div>And as a nice side effect - w=
e can finally explain to a beginner why does forward need a template argume=
nt - to be able to forward as different type! (a cop out, =E2=80=A6 or may =
be not)</div></div></blockquote><div><br></div><div>In that example, I&#39;=
m not forwarding as a different type. As far as the compiler is concerned, =
I might be, but actually I&#39;m not.<br></div></div></blockquote><div><br>=
</div><div>You are building your own type-system. <span style=3D"display:in=
line!important;float:none;background-color:transparent;color:rgb(34,34,34);=
font-family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13=
px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:nor=
mal;text-align:left;text-decoration:none;text-indent:0px;text-transform:non=
e;white-space:normal;word-spacing:0px">You are forwarding A&lt;B&gt; as B.=
=C2=A0</span><br></div><div><br></div><div>I guess it can be done, we can i=
magine some interface like begin() end() for for or get() for structure bin=
ding, but these are out of scope.</div></div></blockquote><div><br></div><d=
iv>What I wanted to say: it is currently possible to write that kind of, it=
 should still be possible with what you propose.</div><div>I don&#39;t want=
 such a collapse_t to be in the standard at all. But it is possible to writ=
e it and use it.</div><div>And to some extent (not this particular example)=
, it is used.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div><br></div><div>You can share your concrete =
needs, might add Future Direction section or something.=C2=A0</div><div>For=
 now I care about to have language level tools to have &quot;zero overhead&=
quot; language level syntax to use them.</div><div><br></div></div></blockq=
uote><div><br></div><div>Agreed.<br></div><div>=C2=A0</div><blockquote clas=
s=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><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></div><div>=C2=A0</div><blockq=
uote 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><div><br><=
/div><div>=C2=A0=E2=80=A6...</div></div></blockquote><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><br></div><div><br></div><div>Besid=
es, given</div><div><br></div><div><font face=3D"courier new,monospace">aut=
o&amp; a =3D geta();</font></div><div><font face=3D"courier new,monospace">=
<br></font></div><div>These two would be equivalent.=C2=A0</div><div><br></=
div><div><font face=3D"courier new,monospace">oms(a&amp;&amp;&gt;);</font><=
/div><div><font face=3D"courier new,monospace">oms(a);=C2=A0</font></div></=
div></blockquote><div><br></div><div>Here, he is being explicit that he doe=
sn&#39;t use <span style=3D"font-family:courier new,monospace">a</span> aft=
er <span style=3D"font-family:courier new,monospace">a&amp;&amp;&gt;</span>=
 (despite doing it anyway, but I&#39;m pretty sure you put the second line =
just for comparison).</div><div>But the function that returned the referenc=
e in the first place might need the object in the future. So it shouldn&#39=
;t be implicitly moved. That would be dangerous.<br></div><div><br></div><d=
iv>However:</div><div><div style=3D"background-color:rgb(250,250,250);borde=
r-color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><s=
pan style=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</=
span><span style=3D"color:#000"> a </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> geta</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"> b </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> getb</span><span style=3D"color:#660">();<=
/span><span style=3D"color:#000"><br><br>oms</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">a</span><span style=3D"color:#660">);=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">// wil=
l use it afterwards</span><span style=3D"color:#000"><br>oms</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#000">a</span><span style=
=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </span><=
span style=3D"color:#800">// will not use it afterwards</span><span style=
=3D"color:#000"><br>oms</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">b</span><span style=3D"color:#660">&amp;&amp;&gt;);</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#800">//will not us=
e it afterwards</span><span style=3D"color:#000"><br></span></div></code></=
div></div><div>If <span style=3D"font-family:courier new,monospace">a</span=
> is a rvalue reference, <span style=3D"font-family:courier new,monospace">=
a&amp;&amp;&gt;</span> will correctly move it.</div><div>If <span style=3D"=
font-family:courier new,monospace">a</span> happens to be a lvalue referenc=
e, it will not be moved, but just forwarded as is.</div></div></blockquote>=
<div><br></div><div><br></div><div>=C2=A0At the moment &amp;&amp;&gt; will =
behave EXACTLY as you described.=C2=A0</div><div><br></div></div></blockquo=
te><div><br></div><div>Exactly in those cases, not in the <span style=3D"fo=
nt-family: courier new, monospace;">auto&amp;</span> case. I just wanted to=
 highlight the differences in those cases.<br></div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div><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>As <span style=3D"font-family:courier new,monospace">b</span> ca=
nnot be a reference (that&#39;s how auto works), <span style=3D"font-family=
:courier new,monospace">b</span> will be moved: there is no outside world.<=
br></div><div><br></div><div>Now:</div><div><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"co=
lor:#660">&amp;&amp;</span><span style=3D"color:#000"> a </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> geta</span><span styl=
e=3D"color:#660">();</span><span style=3D"color:#000"><br><br>oms</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">move</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">a</span><span style=
=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></cod=
e></div>Will move <span style=3D"font-family:courier new,monospace">a</span=
> even if <span style=3D"font-family:courier new,monospace">a</span> is an =
lvalue reference, even if the object was still needed somewhere else (so to=
 be used with caution).<br></div></div></blockquote><div><br></div><div><br=
></div><div>And this is EXACTLY why move will not be deprecated - to force-=
cast a collapsing reference.=C2=A0</div><div><br></div><div><br></div><div>=
I am a bit confused.=C2=A0</div><div>I think you think about <font face=3D"=
courier new,monospace">auto&amp;&amp;</font> to be the type of <font face=
=3D"courier new,monospace">decltype(a), <font face=3D"arial,sans-serif">but=
 I think of it as collapsing reference because at it is at that point,=C2=
=A0</font></font></div><div><font face=3D"courier new,monospace"><font face=
=3D"arial,sans-serif">when it is still a collapsing reference, that the com=
piler will inject the correct impl of give. After collapse is way too late,=
 of course.=C2=A0</font></font></div></div></blockquote><div><br></div><div=
>I don&#39;t think about auto&amp;&amp; as decltype(a): it is not the same.=
 But this is irrelevant to my point.</div><div>You want to give a different=
 behavior to auto&amp;&amp; because it collapses references.</div><div>That=
&#39;s exactly the point I disagree.</div><div>Currently, there is no way t=
o tell when there is reference collapsing. And that&#39;s perfect because i=
t is a tricky, yet useful, feature of C++.</div><div>If you make something =
behaving differently when there is reference collapsing and where there isn=
&#39;t, the language will get more confusing.</div><div><br></div><div>I wo=
uld expect this:</div><div><div style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyp=
rint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">using</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> A </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #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;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>A</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> j <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>foo</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">j</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">&amp;&amp;&gt;);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span></div></code></div>to stay equivalent t=
o this:</div><div><div style=3D"background-color: rgb(250, 250, 250); borde=
r-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; overfl=
ow-wrap: break-word;" class=3D"prettyprint"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> 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><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">0</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: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">j </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>foo</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">j</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&amp;&amp;&gt;);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span></div></code></div></div>=
<div><br></div><div>Because in both cases, j have the exact same type.</div=
><div>With what you propose, they will have different behavior because of t=
he way they are declared while being the same type.</div><div>And what abou=
t:</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">using</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 A </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">using</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> A</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&amp;&amp;;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</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><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>B j </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> i</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
j</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp=
;&gt;);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">// shall it =
be moved?</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br></span></div></code></div><br><br></div><div>This would be completely ne=
w and unusual in the language. This is what I want to avoid.</div><div>The =
type of the variable alone should be enough to decide what to do. (the type=
 of the expression is obviously not enough).</div><div>All my examples show=
 you what kind of code would behave differently.<br></div><div><br></div><d=
iv>Just to clarify things a bit. If I insist, it is because I really want t=
o help you finding the problems with your approach (Whatever your approach =
could be).</div><div>While I do prefer my solution, yours is also interesti=
ng ;)<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/3e258822-7ebf-4de7-9bae-43d280efde09%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3e258822-7ebf-4de7-9bae-43d280efde09=
%40isocpp.org</a>.<br />

------=_Part_58743_1976514343.1528658701614--

------=_Part_58742_1928786916.1528658701612--

.


Author: mihailnajdenov@gmail.com
Date: Mon, 11 Jun 2018 01:07:33 -0700 (PDT)
Raw View
------=_Part_98478_1890930456.1528704453474
Content-Type: multipart/alternative;
 boundary="----=_Part_98479_1214406259.1528704453476"

------=_Part_98479_1214406259.1528704453476
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>
>>
>>
>> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote:
>>>
>>>
>>>
>>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9c=
rit :
>>>>
>>>>
>>>>
>>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com=20
>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a=20
>>>>> =C3=A9crit :
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=20
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>>>> =C3=A9crit :...
>>>>>>>
>>>>>>
>>>>> But you can always imagine some meta-function that give the same=20
>>>>> result as reference collapsing without relying on reference collapsin=
g, and=20
>>>>> that being used as a function parameter.
>>>>> Reference collapsing is a bit like "forwarding" reference: once it ha=
s=20
>>>>> happened, it should behave the same as if never happened in the first=
 place=20
>>>>> if the types are equals.
>>>>>
>>>>> template <class T> struct collapse      { using type =3D T&&; };
>>>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=
=20
>>>>> Optimization for trivial types=20
>>>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>>>
>>>>>
>>>>> template <class T>
>>>>> struct Helper {
>>>>>   void operator()(collapse_t<T> t) {
>>>>>     bar(std::forward<T>(t)); // What do you do here?
>>>>> };
>>>>>
>>>>> template <class T>
>>>>> void foo(T&& t) {
>>>>>   Helper<T>{}(std::forward<T>(t));
>>>>> }
>>>>> =20
>>>>>
>>>>
>>>>
>>>> In this case you are forwarding as a different type. This is the reaso=
n=20
>>>> std::forward will not be deprecated.=20
>>>> And as a nice side effect - we can finally explain to a beginner why=
=20
>>>> does forward need a template argument - to be able to forward as diffe=
rent=20
>>>> type! (a cop out, =E2=80=A6 or may be not)
>>>>
>>>
>>> In that example, I'm not forwarding as a different type. As far as the=
=20
>>> compiler is concerned, I might be, but actually I'm not.
>>>
>>
>> You are building your own type-system. You are forwarding A<B> as B.=20
>>
>> I guess it can be done, we can imagine some interface like begin() end()=
=20
>> for for or get() for structure binding, but these are out of scope.
>>
>
> What I wanted to say: it is currently possible to write that kind of, it=
=20
> should still be possible with what you propose.
>


It might be nice but, I'll not go as far as to say "it should" as reference=
=20
collapsing and casting are language level*. *

All I am doing, I am letting the compiler pick the correct static_cast<>=20
because in my view this is 100% statically deterministic.

If you want extension points - ideas and requirements are welcome. Honestly=
=20
I can't even write the requirements at this point.

Sidenote: yeah, I skimmed over collapse_t. It is not a different type.=20
However you are implementing language level feature with templates.=20
This is the same as how we had move semantics in C++03 (the auto_ptr=20
implementation)
=20
=20

> I don't want such a collapse_t to be in the standard at all. But it is=20
> possible to write it and use it.
> And to some extent (not this particular example), it is used.
> =20
>
>>
>> You can share your concrete needs, might add Future Direction section or=
=20
>> something.=20
>> For now I care about to have language level tools to have "zero overhead=
"=20
>> language level syntax to use them.
>>
>>
> Agreed.
> =20
>
>> =20
>>>
>>>>
>>>>
>>>>  =E2=80=A6...
>>>>
>>>
>>>>
>>>> Besides, given
>>>>
>>>> auto& a =3D geta();
>>>>
>>>> These two would be equivalent.=20
>>>>
>>>> oms(a&&>);
>>>> oms(a);=20
>>>>
>>>
>>> Here, he is being explicit that he doesn't use a after a&&> (despite=20
>>> doing it anyway, but I'm pretty sure you put the second line just for=
=20
>>> comparison).
>>> But the function that returned the reference in the first place might=
=20
>>> need the object in the future. So it shouldn't be implicitly moved. Tha=
t=20
>>> would be dangerous.
>>>
>>> However:
>>> auto&& a =3D geta();
>>> auto b =3D getb();
>>>
>>> oms(a); // will use it afterwards
>>> oms(a&&>); // will not use it afterwards
>>> oms(b&&>); //will not use it afterwards
>>> If a is a rvalue reference, a&&> will correctly move it.
>>> If a happens to be a lvalue reference, it will not be moved, but just=
=20
>>> forwarded as is.
>>>
>>
>>
>>  At the moment &&> will behave EXACTLY as you described.=20
>>
>>
> Exactly in those cases, not in the auto& case. I just wanted to highlight=
=20
> the differences in those cases.
> =20
>
>>
>> =20
>>
>>> As b cannot be a reference (that's how auto works), b will be moved:=20
>>> there is no outside world.
>>>
>>> Now:
>>> auto&& a =3D geta();
>>>
>>> oms(std::move(a));
>>> Will move a even if a is an lvalue reference, even if the object was=20
>>> still needed somewhere else (so to be used with caution).
>>>
>>
>>
>> And this is EXACTLY why move will not be deprecated - to force-cast a=20
>> collapsing reference.=20
>>
>>
>> I am a bit confused.=20
>> I think you think about auto&& to be the type of decltype(a), but I=20
>> think of it as collapsing reference because at it is at that point,=20
>> when it is still a collapsing reference, that the compiler will inject=
=20
>> the correct impl of give. After collapse is way too late, of course.=20
>>
>
> I don't think about auto&& as decltype(a): it is not the same. But this i=
s=20
> irrelevant to my point.
> You want to give a different behavior to auto&& because it collapses=20
> references.
>


But *it is* different. It is not a type declaration, its a language level=
=20
template-expression declaration, your collapser_t build-in if you will.

 I have full right to treat these as special, as the language already does.

=20

> That's exactly the point I disagree.
> Currently, there is no way to tell when there is reference collapsing. An=
d=20
> that's perfect because it is a tricky, yet useful, feature of C++.
>
=20

After few template processing or argument passing it is lost, yes.=20

But at the top level is clear  - syntax of the form T&& will trigger=20
reference collapsing (if any), and it is always correct to static_cast<T&&>=
=20
to pass it on

In a way that case is the easiest, because the language is already smart=20
about it.

=20

> If you make something behaving differently when there is reference=20
> collapsing and where there isn't, the language will get more confusing.
>


As said, the language already does,  static_cast<T&&> no longer returns=20
rvalue ref (as it "obviously should") - it returns &. yes this is=20
confusing, but that's how it is.

=20

>
> I would expect this:
> using A =3D int&;
> int i =3D 0;
> A&& j =3D i;
> foo(j&&>);
> to stay equivalent to this:
> int i =3D 0;
> int &j =3D i;
> foo(j&&>);
>
> Because in both cases, j have the exact same type.
> With what you propose, they will have different behavior because of the=
=20
> way they are declared while being the same type.
>
=20

Today is not very different. If you forward<int>(j) - it is moved, if forwa=
rd<A>(j)=20
- it will be forwarded.=20

And comes the question. What is the intend of the user? Does he want to=20
forward a &? Why on earth he even THINKS he can do that?!?

Wasn't he told in school "you forward only forwarding references"?=20

In order to "forward" an & - you MUST pass through reference collapsing.=20
These are the rules today! You must typedef A&& or you must decltype(x) to=
=20
get the exact type.=20

So, with an operator it is obvious what will be done in what case. If the=
=20
user &&> a reference (he sees its an reference, in code), by todays rules,=
=20
this MUST be a move, on another hand, is the type is hidden behind a=20
collapse (he sees its a T&&) - it MUST be forward. =20
(Needless to say, you never want to "forward" a & - as you can just pass=20
the variable as is.)


Sidenote. Probably the example you are looking for:

using A =3D C&;
A j =3D c;
f(std::forward<A>(j));

using A =3D C&;
A&& j =3D c;
f(std::forward<A>(j));

Same today, different with &&>.=20

But as said, it will still be correct (arguably more correct) , as the user=
=20
is explicit what he declares and what he wants.

=20

> And what about:
> using A =3D int&;
> using B =3D A&&;
>
> int i =3D 0;
> B j =3D i;
> foo(j&&>); // shall it be moved?
>
>
Of course not. B is reference collapsing "expression"/"type", reference=20
collapses are AWAYS forwarded. =20
=20

>
> This would be completely new and unusual in the language. This is what I=
=20
> want to avoid.
> The type of the variable alone should be enough to decide what to do. (th=
e=20
> type of the expression is obviously not enough).
>


As said, I am taping on the level before the type of the variable becomes=
=20
finalized. When the auto&& is just an expression to capture the type,=20
whatever it is.

Only at this point, we can have no-brain forward-or-move-you-know-best,=20
because the compiler (preprocessor I guess, because there is no=20
instantiations) has all the information to do the right thing.=20

At type level this can not be solved.=20

=20

> All my examples show you what kind of code would behave differently.
>
> Just to clarify things a bit. If I insist, it is because I really want to=
=20
> help you finding the problems with your approach (Whatever your approach=
=20
> could be).
> While I do prefer my solution, yours is also interesting ;)
>

I am very grateful to you, because with your use cases outside forwarding=
=20
references (as per The Standard) it helped me find the actual valid uses.=
=20
After all both operator()(A&&...) and auto&& var =3D =E2=80=A6 are not  for=
warding=20
references (as per The Standard)


--=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/944d492c-ded1-4fb3-a937-6cc40b581ba8%40isocpp.or=
g.

------=_Part_98479_1214406259.1528704453476
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, flo=
ria...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><br><br>Le dimanche 10 juin 2018 20:59:45 UTC+2, <a>mihailn...@gm=
ail.com</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>flori=
a...@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"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.=
com</a> 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"><div dir=
=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...=
@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com=
</a> a =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div><br><=
/div><div>But you can always imagine some meta-function that give the same =
result as reference collapsing without relying on reference collapsing, and=
 that being used as a function parameter.</div><div>Reference collapsing is=
 a bit like &quot;forwarding&quot; reference: once it has happened, it shou=
ld behave the same as if never happened in the first place if the types are=
 equals.</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#008">template</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008=
">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">using</span><span style=3D"color:#000"> type </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> collapse</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&=
amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">using</sp=
an><span style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> collapse</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> ty=
pe </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
><code><span style=3D"color:#000"><br></span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">* &gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">using</span><span style=3D"color:#000">=
 type </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
></span></code></span><span style=3D"color:#000"><code><span style=3D"color=
:#000"><code><span style=3D"color:#800"> // Optimization for trivial types =
</span><span style=3D"color:#000"><br></span></code></span></code></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">using</span>=
<span style=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>typename</span><span style=3D"color:#000"> collapse</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"col=
or:#660">&gt;::</span><span style=3D"color:#000">type</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br><br><br></span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</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">struct</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Helper</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">operator</spa=
n><span style=3D"color:#660">()(</span><span style=3D"color:#000">collapse_=
t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> t</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 bar</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">forward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#=
000">t</span><span style=3D"color:#660">));</span><span style=3D"color:#000=
"> </span><span style=3D"color:#800">// What do you do here?</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span sty=
le=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><s=
pan 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:#660">(</span><span style=3D"color:#000">T</span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span>=
<span style=3D"color:#606">Helper</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</=
span><span style=3D"color:#000">t</span><span style=3D"color:#660">)<wbr>);=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"></span><br></div></code></div></div><div>=
=C2=A0</div></div></blockquote><div><br></div><div><br></div><div>In this c=
ase you are forwarding as a different type. This is the reason std::forward=
 will not be deprecated.=C2=A0</div><div>And as a nice side effect - we can=
 finally explain to a beginner why does forward need a template argument - =
to be able to forward as different type! (a cop out, =E2=80=A6 or may be no=
t)</div></div></blockquote><div><br></div><div>In that example, I&#39;m not=
 forwarding as a different type. As far as the compiler is concerned, I mig=
ht be, but actually I&#39;m not.<br></div></div></blockquote><div><br></div=
><div>You are building your own type-system. <span style=3D"display:inline!=
important;float:none;background-color:transparent;color:rgb(34,34,34);font-=
family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;fo=
nt-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;t=
ext-align:left;text-decoration:none;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px">You are forwarding A&lt;B&gt; as B.=C2=A0=
</span><br></div><div><br></div><div>I guess it can be done, we can imagine=
 some interface like begin() end() for for or get() for structure binding, =
but these are out of scope.</div></div></blockquote><div><br></div><div>Wha=
t I wanted to say: it is currently possible to write that kind of, it shoul=
d still be possible with what you propose.</div></div></blockquote><div><br=
></div><div><br></div><div>It might be nice but, I&#39;ll not go as far as =
to say &quot;it should&quot; as reference collapsing and casting are langua=
ge level<i>.=C2=A0</i></div><div><i></i><br></div><div>All I am doing, I am=
 letting the compiler pick the correct static_cast&lt;&gt; because in my vi=
ew this is 100% statically deterministic.</div><div><br></div><div>If you w=
ant extension points - ideas and requirements are welcome. Honestly I can&#=
39;t even write the=C2=A0<span style=3D"display: inline !important; float: =
none; background-color: transparent; color: rgb(34, 34, 34); font-family: &=
quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-st=
yle: normal; font-variant: normal; font-weight: 400; letter-spacing: normal=
; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; te=
xt-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; wo=
rd-spacing: 0px;">requirements at this point.</span><span style=3D"display:=
 inline !important; float: none; background-color: transparent; color: rgb(=
34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f; font-size: 13px; font-style: normal; font-variant: normal; font-weight: =
400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration:=
 none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0=
px; white-space: normal; word-spacing: 0px;"><br></span></div><div><span st=
yle=3D"display: inline !important; float: none; background-color: transpare=
nt; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></di=
v><div><span style=3D"display: inline !important; float: none; background-c=
olor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-=
variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text=
-align: left; text-decoration: none; text-indent: 0px; text-transform: none=
; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=
Sidenote: yeah, I skimmed over=C2=A0</span><span style=3D"background-color:=
 transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: in=
line; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helveti=
ca&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; -web=
kit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">collap=
se_t. It is not a different type. However you are implementing language lev=
el feature with templates.=C2=A0</span><span style=3D"background-color: tra=
nsparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; =
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stre=
tch; border-image-slice: 100%; border-image-source: none; border-image-widt=
h: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-l=
eft-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: no=
ne; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-=
style: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline=
; float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&a=
mp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span=
></div><div><span style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-family:=
 &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">This is the same as how we had move s=
emantics in C++03 (the auto_ptr implementation)</span><b></b><i></i><u></u>=
<sub></sub><sup></sup><strike></strike><br></div><div>=C2=A0</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=
>I don&#39;t want such a collapse_t to be in the standard at all. But it is=
 possible to write it and use it.</div><div>And to some extent (not this pa=
rticular example), it is used.<br></div><div>=C2=A0</div><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><br></div><div>You can share y=
our concrete needs, might add Future Direction section or something.=C2=A0<=
/div><div>For now I care about to have language level tools to have &quot;z=
ero overhead&quot; language level syntax to use them.</div><div><br></div><=
/div></blockquote><div><br></div><div>Agreed.<br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></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></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></div><di=
v><br></div><div>=C2=A0=E2=80=A6...</div></div></blockquote><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><br></div><div><br></div><di=
v>Besides, given</div><div><br></div><div><font face=3D"courier new,monospa=
ce">auto&amp; a =3D geta();</font></div><div><font face=3D"courier new,mono=
space"><br></font></div><div>These two would be equivalent.=C2=A0</div><div=
><br></div><div><font face=3D"courier new,monospace">oms(a&amp;&amp;&gt;);<=
/font></div><div><font face=3D"courier new,monospace">oms(a);=C2=A0</font><=
/div></div></blockquote><div><br></div><div>Here, he is being explicit that=
 he doesn&#39;t use <span style=3D"font-family:courier new,monospace">a</sp=
an> after <span style=3D"font-family:courier new,monospace">a&amp;&amp;&gt;=
</span> (despite doing it anyway, but I&#39;m pretty sure you put the secon=
d line just for comparison).</div><div>But the function that returned the r=
eference in the first place might need the object in the future. So it shou=
ldn&#39;t be implicitly moved. That would be dangerous.<br></div><div><br><=
/div><div>However:</div><div><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</span><span style=3D"color:#660">&amp;=
&amp;</span><span style=3D"color:#000"> a </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> geta</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"> b </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> getb</span><span style=3D"color:#66=
0">();</span><span style=3D"color:#000"><br><br>oms</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">a</span><span style=3D"color:#=
660">);</span><span style=3D"color:#000"> </span><span style=3D"color:#800"=
>// will use it afterwards</span><span style=3D"color:#000"><br>oms</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">a</span><span =
style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#800">// will not use it afterwards</span><span st=
yle=3D"color:#000"><br>oms</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">b</span><span style=3D"color:#660">&amp;&amp;&gt;);</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#800">//will not=
 use it afterwards</span><span style=3D"color:#000"><br></span></div></code=
></div></div><div>If <span style=3D"font-family:courier new,monospace">a</s=
pan> is a rvalue reference, <span style=3D"font-family:courier new,monospac=
e">a&amp;&amp;&gt;</span> will correctly move it.</div><div>If <span style=
=3D"font-family:courier new,monospace">a</span> happens to be a lvalue refe=
rence, it will not be moved, but just forwarded as is.</div></div></blockqu=
ote><div><br></div><div><br></div><div>=C2=A0At the moment &amp;&amp;&gt; w=
ill behave EXACTLY as you described.=C2=A0</div><div><br></div></div></bloc=
kquote><div><br></div><div>Exactly in those cases, not in the <span style=
=3D"font-family:courier new,monospace">auto&amp;</span> case. I just wanted=
 to highlight the differences in those cases.<br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div><br><=
/div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>As <span style=3D"font-family:courier new,monospace">b</span> cann=
ot be a reference (that&#39;s how auto works), <span style=3D"font-family:c=
ourier new,monospace">b</span> will be moved: there is no outside world.<br=
></div><div><br></div><div>Now:</div><div><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#660">&amp;&amp;</span><span style=3D"color:#000"> a </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> geta</span><span styl=
e=3D"color:#660">();</span><span style=3D"color:#000"><br><br>oms</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">move</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">a</span><span style=
=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></cod=
e></div>Will move <span style=3D"font-family:courier new,monospace">a</span=
> even if <span style=3D"font-family:courier new,monospace">a</span> is an =
lvalue reference, even if the object was still needed somewhere else (so to=
 be used with caution).<br></div></div></blockquote><div><br></div><div><br=
></div><div>And this is EXACTLY why move will not be deprecated - to force-=
cast a collapsing reference.=C2=A0</div><div><br></div><div><br></div><div>=
I am a bit confused.=C2=A0</div><div>I think you think about <font face=3D"=
courier new,monospace">auto&amp;&amp;</font> to be the type of <font face=
=3D"courier new,monospace">decltype(a), <font face=3D"arial,sans-serif">but=
 I think of it as collapsing reference because at it is at that point,=C2=
=A0</font></font></div><div><font face=3D"courier new,monospace"><font face=
=3D"arial,sans-serif">when it is still a collapsing reference, that the com=
piler will inject the correct impl of give. After collapse is way too late,=
 of course.=C2=A0</font></font></div></div></blockquote><div><br></div><div=
>I don&#39;t think about auto&amp;&amp; as decltype(a): it is not the same.=
 But this is irrelevant to my point.</div><div>You want to give a different=
 behavior to auto&amp;&amp; because it collapses references.</div></div></b=
lockquote><div><br></div><div><br></div><div>But <i>it is</i> different. It=
 is not a type declaration, its a language level template-expression declar=
ation, your collapser_t build-in if you will.</div><div><br></div><div>=C2=
=A0I have full right to treat these as special, as the language already doe=
s.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div>That&#39;s exactly the point I disagree.</d=
iv><div>Currently, there is no way to tell when there is reference collapsi=
ng. And that&#39;s perfect because it is a tricky, yet useful, feature of C=
++.</div></div></blockquote><div>=C2=A0</div><div><br></div><div>After few =
template processing or argument passing it is lost, yes.=C2=A0</div><div><b=
r></div><div>But at the top level is clear=C2=A0 - syntax of the form T&amp=
;&amp; will trigger reference collapsing (if any), and it is always correct=
 to static_cast&lt;T&amp;&amp;&gt; to pass it on</div><div><br></div><div>I=
n a way that case is the easiest, because the language is already smart abo=
ut it.<br></div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div>If you make something behaving diff=
erently when there is reference collapsing and where there isn&#39;t, the l=
anguage will get more confusing.</div></div></blockquote><div><br></div><di=
v><br></div><div>As said, the language already does,=C2=A0<span style=3D"di=
splay: inline !important; float: none; background-color: transparent; color=
: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,san=
s-serif; font-size: 13px; font-style: normal; font-variant: normal; font-we=
ight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decor=
ation: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-wi=
dth: 0px; white-space: normal; word-spacing: 0px;"> static_cast&lt;T&amp;&a=
mp;&gt; no longer returns rvalue ref (as it &quot;obviously should&quot;) -=
 it returns &amp;. yes this is confusing, but that&#39;s how it is.</span><=
/div><div><span style=3D"display: inline !important; float: none; backgroun=
d-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; fo=
nt-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; t=
ext-align: left; text-decoration: none; text-indent: 0px; text-transform: n=
one; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px=
;"><br></span></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></div><div>I would expect this:</div><div>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px"><code><div><span style=3D"color:#00=
8">using</span><span style=3D"color:#000"> A </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>int</span><span style=3D"color:#660">&amp;;</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">int</span><span style=3D"color:#00=
0"> i </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> </span><span style=3D"color:#066">0</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"><br>A</span><span style=3D"color:#660">&amp=
;&amp;</span><span style=3D"color:#000"> j </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> i</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br>foo</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">j</span><span style=3D"color:#660">&amp=
;&amp;&gt;);</span><span style=3D"color:#000"><br></span></div></code></div=
>to stay equivalent to this:</div><div><div style=3D"background-color:rgb(2=
50,250,250);border-color:rgb(187,187,187);border-style:solid;border-width:1=
px"><code><div><span style=3D"color:#008">int</span><span style=3D"color:#0=
00"> i </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#066">0</span><span style=3D"color:#660">;<=
/span><span style=3D"color:#000"><br></span><span style=3D"color:#008">int<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000">j </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> i</span><span style=3D"color:#660">;</span><=
span style=3D"color:#000"><br>foo</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt=
;);</span><span style=3D"color:#000"><br></span></div></code></div></div><d=
iv><br></div><div>Because in both cases, j have the exact same type.</div><=
div>With what you propose, they will have different behavior because of the=
 way they are declared while being the same type.</div></div></blockquote><=
div>=C2=A0</div><div><br></div><div>Today is not very different. If you for=
ward&lt;int&gt;(j) - it is moved, if=C2=A0<span style=3D"display: inline !i=
mportant; float: none; background-color: transparent; color: rgb(34, 34, 34=
); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-si=
ze: 13px; font-style: normal; font-variant: normal; font-weight: 400; lette=
r-spacing: normal; orphans: 2; text-align: left; text-decoration: none; tex=
t-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-=
space: normal; word-spacing: 0px;">forward&lt;A&gt;(j) - it will be forward=
ed.=C2=A0</span></div><div><span style=3D"display: inline !important; float=
: none; background-color: transparent; color: rgb(34, 34, 34); font-family:=
 &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-=
style: normal; font-variant: normal; font-weight: 400; letter-spacing: norm=
al; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; =
text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; =
word-spacing: 0px;"><br></span></div><div><span style=3D"display: inline !i=
mportant; float: none; background-color: transparent; color: rgb(34, 34, 34=
); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-si=
ze: 13px; font-style: normal; font-variant: normal; font-weight: 400; lette=
r-spacing: normal; orphans: 2; text-align: left; text-decoration: none; tex=
t-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-=
space: normal; word-spacing: 0px;">And comes the question. What is the inte=
nd of the user? Does he want to forward a &amp;? Why on earth he even THINK=
S he can do that?!?</span></div><div><span style=3D"display: inline !import=
ant; float: none; background-color: transparent; color: rgb(34, 34, 34); fo=
nt-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 1=
3px; font-style: normal; font-variant: normal; font-weight: 400; letter-spa=
cing: normal; orphans: 2; text-align: left; text-decoration: none; text-ind=
ent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space=
: normal; word-spacing: 0px;"><br></span></div><div><span style=3D"display:=
 inline !important; float: none; background-color: transparent; color: rgb(=
34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-seri=
f; font-size: 13px; font-style: normal; font-variant: normal; font-weight: =
400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration:=
 none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0=
px; white-space: normal; word-spacing: 0px;">Wasn&#39;t he told in school &=
quot;you forward only forwarding references&quot;?=C2=A0</span></div><div><=
span style=3D"display: inline !important; float: none; background-color: tr=
ansparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: =
left; text-decoration: none; text-indent: 0px; text-transform: none; -webki=
t-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></sp=
an></div><div><span style=3D"display: inline !important; float: none; backg=
round-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&=
quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal=
; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: =
2; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
 0px;">In order to &quot;forward&quot; an &amp; - you MUST pass through ref=
erence collapsing. These are the rules today! </span><span style=3D"display=
: inline !important; float: none; background-color: transparent; color: rgb=
(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;">You must typedef A&amp;&amp; =
or you must decltype(x) to get the exact type.=C2=A0</span></div><div><span=
 style=3D"display: inline !important; float: none; background-color: transp=
arent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left=
; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-te=
xt-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span><=
/div><div><span style=3D"display: inline !important; float: none; backgroun=
d-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot=
;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; fo=
nt-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; t=
ext-align: left; text-decoration: none; text-indent: 0px; text-transform: n=
one; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px=
;">So, with an operator it is obvious what will be done in what case. If th=
e user &amp;&amp;&gt; a reference (he sees its an reference, in code), by t=
odays rules, this MUST be a move, on another hand, is the type is hidden be=
hind a collapse (he sees its a T&amp;&amp;) - it MUST be forward. =C2=A0</s=
pan></div><div><span style=3D"text-align: left; color: rgb(34, 34, 34); tex=
t-transform: none; text-indent: 0px; letter-spacing: normal; font-family: &=
quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-va=
riant: normal; word-spacing: 0px; display: inline !important; white-space: =
normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; background=
-color: transparent;"><span style=3D"display: inline !important; float: non=
e; background-color: transparent; color: rgb(34, 34, 34); font-family: &quo=
t;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style=
: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; o=
rphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-=
transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-=
spacing: 0px;">(Needless to say, you never want to &quot;forward&quot; a &a=
mp; - as you can just pass the variable as is.)</span></span></div><div><sp=
an style=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none;=
 text-indent: 0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif; font-size: 13px; font-variant: normal; wor=
d-spacing: 0px; display: inline !important; white-space: normal; orphans: 2=
; float: none; -webkit-text-stroke-width: 0px; background-color: transparen=
t;"><span style=3D"display: inline !important; float: none; background-colo=
r: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quo=
t;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-var=
iant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-al=
ign: left; text-decoration: none; text-indent: 0px; text-transform: none; -=
webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br=
></span></span></div><div><span style=3D"text-align: left; color: rgb(34, 3=
4, 34); text-transform: none; text-indent: 0px; letter-spacing: normal; fon=
t-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13=
px; font-variant: normal; word-spacing: 0px; display: inline !important; wh=
ite-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px;=
 background-color: transparent;"><span style=3D"display: inline !important;=
 float: none; background-color: transparent; color: rgb(34, 34, 34); font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; orphans: 2; text-align: left; text-decoration: none; text-indent:=
 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;"><br></span></span></div><div><span style=3D"text-=
align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px=
; letter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-variant: normal; word-spacing: 0px; d=
isplay: inline !important; white-space: normal; orphans: 2; float: none; -w=
ebkit-text-stroke-width: 0px; background-color: transparent;"><span style=
=3D"display: inline !important; float: none; background-color: transparent;=
 color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quo=
t;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; f=
ont-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text=
-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-str=
oke-width: 0px; white-space: normal; word-spacing: 0px;">Sidenote. Probably=
 the example you are looking for:</span></span></div><div><span style=3D"te=
xt-align: left; color: rgb(34, 34, 34); text-transform: none; text-indent: =
0px; letter-spacing: normal; font-family: &quot;Arial&quot;,&quot;Helvetica=
&quot;,sans-serif; font-size: 13px; font-variant: normal; word-spacing: 0px=
; display: inline !important; white-space: normal; orphans: 2; float: none;=
 -webkit-text-stroke-width: 0px; background-color: transparent;"><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></span=
></div><div><span style=3D"text-align: left; color: rgb(34, 34, 34); text-t=
ransform: none; text-indent: 0px; letter-spacing: normal; font-size: 13px; =
font-variant: normal; word-spacing: 0px; display: inline !important; white-=
space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; bac=
kground-color: transparent;"><span style=3D"text-align: left; color: rgb(34=
, 34, 34); text-transform: none; text-indent: 0px; letter-spacing: normal; =
font-size: 13px; font-style: normal; font-variant: normal; font-weight: 400=
; text-decoration: none; word-spacing: 0px; display: inline !important; whi=
te-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; =
background-color: transparent;"><font face=3D"courier new,monospace">using =
A =3D C&amp;;</font></span></span></div><div><span style=3D"text-align: lef=
t; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; letter-s=
pacing: normal; font-size: 13px; font-variant: normal; word-spacing: 0px; d=
isplay: inline !important; white-space: normal; orphans: 2; float: none; -w=
ebkit-text-stroke-width: 0px; background-color: transparent;"><span style=
=3D"text-align: left; color: rgb(34, 34, 34); text-transform: none; text-in=
dent: 0px; letter-spacing: normal; font-size: 13px; font-style: normal; fon=
t-variant: normal; font-weight: 400; text-decoration: none; word-spacing: 0=
px; display: inline !important; white-space: normal; orphans: 2; float: non=
e; -webkit-text-stroke-width: 0px; background-color: transparent;"><font fa=
ce=3D"courier new,monospace">A j =3D c;<br></font><div><font face=3D"courie=
r new,monospace">f(std::forward&lt;A&gt;(j));</font></div><div><br></div></=
span></span></div><div><span style=3D"text-align: left; color: rgb(34, 34, =
34); text-transform: none; text-indent: 0px; letter-spacing: normal; font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px;=
 font-variant: normal; word-spacing: 0px; display: inline !important; white=
-space: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; ba=
ckground-color: transparent;"><font face=3D"courier new,monospace"></font><=
div style=3D"background-color: transparent; border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
 border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color=
: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helveti=
ca&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant:=
 normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; -web=
kit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><span =
style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rg=
b(34, 34, 34); display: inline; float: none; font-family: &amp;quot;Arial&a=
mp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-st=
yle: normal; font-variant: normal; font-weight: 400; letter-spacing: normal=
; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;=
 orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pa=
dding-top: 0px; text-align: left; text-decoration: none; text-indent: 0px; =
text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; =
word-spacing: 0px;"><span style=3D"background-color: transparent; border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; color: rgb(34, 34, 34); display: inline; float: none; font=
-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif=
; font-size: 13px; font-style: normal; font-variant: normal; font-weight: 4=
00; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-ri=
ght: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0=
px; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;"><font face=3D"courier new,mon=
ospace" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style:=
 none; border-bottom-width: 0px; border-image-outset: 0; border-image-repea=
t: stretch; border-image-slice: 100%; border-image-source: none; border-ima=
ge-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; b=
order-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-st=
yle: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bord=
er-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left:=
 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left=
: 0px; padding-right: 0px; padding-top: 0px;">using A =3D C&amp;;</font></s=
pan></span></div><div style=3D"background-color: transparent; border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;=
,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; margin=
-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans=
: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-to=
p: 0px; text-align: left; text-decoration: none; text-indent: 0px; text-tra=
nsform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spa=
cing: 0px;"><span style=3D"background-color: transparent; border-bottom-col=
or: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; b=
order-image-outset: 0; border-image-repeat: stretch; border-image-slice: 10=
0%; border-image-source: none; border-image-width: 1; border-left-color: rg=
b(34, 34, 34); border-left-style: none; border-left-width: 0px; border-righ=
t-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px=
; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-wid=
th: 0px; color: rgb(34, 34, 34); display: inline; float: none; font-family:=
 &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-s=
ize: 13px; font-style: normal; font-variant: normal; font-weight: 400; lett=
er-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;"><span style=3D"background-color: tran=
sparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; b=
order-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stret=
ch; border-image-slice: 100%; border-image-source: none; border-image-width=
: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-le=
ft-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: non=
e; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-s=
tyle: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline;=
 float: none; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&am=
p;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norm=
al; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-le=
ft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: lef=
t; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-t=
ext-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=
=3D"courier new,monospace" style=3D"border-bottom-color: rgb(34, 34, 34); b=
order-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0;=
 border-image-repeat: stretch; border-image-slice: 100%; border-image-sourc=
e: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-=
left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 3=
4); border-right-style: none; border-right-width: 0px; border-top-color: rg=
b(34, 34, 34); border-top-style: none; border-top-width: 0px; margin-bottom=
: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom=
: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">A&amp;&amp=
; j =3D c;<br style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-=
style: none; border-bottom-width: 0px; border-image-outset: 0; border-image=
-repeat: stretch; border-image-slice: 100%; border-image-source: none; bord=
er-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: n=
one; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-ri=
ght-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34)=
; border-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin=
-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; paddin=
g-left: 0px; padding-right: 0px; padding-top: 0px;"></font><div style=3D"bo=
rder-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-botto=
m-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-=
image-slice: 100%; border-image-source: none; border-image-width: 1; border=
-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-r=
ight-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none;=
 border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px;"><font face=3D"courier new,monospace" style=3D"bo=
rder-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-botto=
m-width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-=
image-slice: 100%; border-image-source: none; border-image-width: 1; border=
-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0=
px; border-right-color: rgb(34, 34, 34); border-right-style: none; border-r=
ight-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none;=
 border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right:=
 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-righ=
t: 0px; padding-top: 0px;">f(std::forward&lt;A&gt;(j));</font></div><div st=
yle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pad=
ding-right: 0px; padding-top: 0px;"><font face=3D"courier new,monospace" st=
yle=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
 border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; marg=
in-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; pad=
ding-right: 0px; padding-top: 0px;"><br></font></div><div style=3D"border-b=
ottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-widt=
h: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-=
slice: 100%; border-image-source: none; border-image-width: 1; border-left-=
color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bo=
rder-right-color: rgb(34, 34, 34); border-right-style: none; border-right-w=
idth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; borde=
r-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px=
; padding-top: 0px;"><font face=3D"arial,sans-serif" style=3D"border-bottom=
-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0p=
x; border-image-outset: 0; border-image-repeat: stretch; border-image-slice=
: 100%; border-image-source: none; border-image-width: 1; border-left-color=
: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; border-=
right-color: rgb(34, 34, 34); border-right-style: none; border-right-width:=
 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border-top=
-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margi=
n-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; pad=
ding-top: 0px;">Same today, different with &amp;&amp;&gt;.=C2=A0</font></di=
v><div style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: =
none; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat=
: stretch; border-image-slice: 100%; border-image-source: none; border-imag=
e-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bo=
rder-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-sty=
le: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); borde=
r-top-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left:=
 0px; padding-right: 0px; padding-top: 0px;"><font face=3D"arial,sans-serif=
" style=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none;=
 border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: str=
etch; border-image-slice: 100%; border-image-source: none; border-image-wid=
th: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-=
left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: n=
one; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top=
-style: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; =
margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px;=
 padding-right: 0px; padding-top: 0px;"><br></font></div><div style=3D"bord=
er-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-=
width: 0px; border-image-outset: 0; border-image-repeat: stretch; border-im=
age-slice: 100%; border-image-source: none; border-image-width: 1; border-l=
eft-color: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px=
; border-right-color: rgb(34, 34, 34); border-right-style: none; border-rig=
ht-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; b=
order-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0=
px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px;"><font face=3D"arial,sans-serif" style=3D"border-bo=
ttom-color: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width=
: 0px; border-image-outset: 0; border-image-repeat: stretch; border-image-s=
lice: 100%; border-image-source: none; border-image-width: 1; border-left-c=
olor: rgb(34, 34, 34); border-left-style: none; border-left-width: 0px; bor=
der-right-color: rgb(34, 34, 34); border-right-style: none; border-right-wi=
dth: 0px; border-top-color: rgb(34, 34, 34); border-top-style: none; border=
-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; m=
argin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px;=
 padding-top: 0px;">But as said, it will still be correct (arguably more co=
rrect) , as the user is explicit what he declares and what he wants.</font>=
<br></div></span></span></div><b></b><i></i><u></u><sub></sub><sup></sup><s=
trike></strike><font face=3D"arial,sans-serif"></font><br></span></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>And what about:</div><div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#008">using</span><span style=3D"color:#000"> A=
 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">int</span><span style=3D"color:#660">&amp;;=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">usi=
ng</span><span style=3D"color:#000"> B </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> A</span><span style=3D"color:#660">&a=
mp;&amp;;</span><span style=3D"color:#000"><br><br></span><span style=3D"co=
lor:#008">int</span><span style=3D"color:#000"> i </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">0</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>B j </span><span style=3D"color:#660">=3D</span><span style=3D"color:#=
000"> i</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br>foo</span><span style=3D"color:#660">(</span><span style=3D"color:#000=
">j</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"=
color:#000"> </span><span style=3D"color:#800">// shall it be moved?</span>=
<span style=3D"color:#000"><br></span></div></code></div><br></div></div></=
blockquote><div><br></div><div>Of course not. B is reference collapsing &qu=
ot;expression&quot;/&quot;type&quot;, reference collapses are AWAYS forward=
ed. =C2=A0</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><div>This would be completely new and un=
usual in the language. This is what I want to avoid.</div><div>The type of =
the variable alone should be enough to decide what to do. (the type of the =
expression is obviously not enough).</div></div></blockquote><div><br></div=
><div><br></div><div>As said, I am taping on the level before the type of t=
he variable becomes finalized. When the auto&amp;&amp; is just an expressio=
n to capture the type, whatever it is.</div><div><br></div><div>Only at thi=
s point, we can have no-brain forward-or-move-you-know-best, because the co=
mpiler (preprocessor I guess, because there is no instantiations) <span sty=
le=3D"display: inline !important; float: none; background-color: transparen=
t; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&q=
uot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal;=
 font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; te=
xt-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-s=
troke-width: 0px; white-space: normal; word-spacing: 0px;">has all the info=
rmation to do the right thing</span>.=C2=A0</div><div><br></div><div>At typ=
e level this can not be solved.=C2=A0</div><div><br></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>All my e=
xamples show you what kind of code would behave differently.<br></div><div>=
<br></div><div>Just to clarify things a bit. If I insist, it is because I r=
eally want to help you finding the problems with your approach (Whatever yo=
ur approach could be).</div><div>While I do prefer my solution, yours is al=
so interesting ;)<br></div></div></blockquote><div><br></div><div>I am very=
 grateful to you, because with your use cases outside forwarding references=
 (as per The Standard) it helped me find the actual valid uses. After all b=
oth operator()(A&amp;&amp;...) and auto&amp;&amp; var =3D =E2=80=A6 are not=
=C2=A0<span style=3D"display: inline !important; float: none; background-co=
lor: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&q=
uot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
 -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"> =
forwarding references (as per The Standard)</span><b></b><i></i><u></u><sub=
></sub><sup></sup><strike></strike><br></div><div><span style=3D"display: i=
nline !important; float: none; background-color: transparent; color: rgb(34=
, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;=
 font-size: 13px; font-style: normal; font-variant: normal; font-weight: 40=
0; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: n=
one; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px=
; white-space: normal; word-spacing: 0px;"><b></b><i></i><u></u><sub></sub>=
<sup></sup><strike></strike><b></b><i></i><u></u><sub></sub><sup></sup><str=
ike></strike><br></span></div><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/944d492c-ded1-4fb3-a937-6cc40b581ba8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/944d492c-ded1-4fb3-a937-6cc40b581ba8=
%40isocpp.org</a>.<br />

------=_Part_98479_1214406259.1528704453476--

------=_Part_98478_1890930456.1528704453474--

.


Author: mihailnajdenov@gmail.com
Date: Mon, 11 Jun 2018 01:17:20 -0700 (PDT)
Raw View
------=_Part_98338_1869311901.1528705040325
Content-Type: multipart/alternative;
 boundary="----=_Part_98339_1705356792.1528705040327"

------=_Part_98339_1705356792.1528705040327
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn...@gmail.com a =C3=A9cri=
t :
>>
>>
>>
>> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote:
>>>
>>>
>>>
>>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9c=
rit :
>>>>
>>>>
>>>>
>>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com=20
>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a=20
>>>>> =C3=A9crit :
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=20
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>>>> =C3=A9crit :...
>>>>>>>
>>>>>>
>>>>> But you can always imagine some meta-function that give the same=20
>>>>> result as reference collapsing without relying on reference collapsin=
g, and=20
>>>>> that being used as a function parameter.
>>>>> Reference collapsing is a bit like "forwarding" reference: once it ha=
s=20
>>>>> happened, it should behave the same as if never happened in the first=
 place=20
>>>>> if the types are equals.
>>>>>
>>>>> template <class T> struct collapse      { using type =3D T&&; };
>>>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=
=20
>>>>> Optimization for trivial types=20
>>>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>>>
>>>>>
>>>>> template <class T>
>>>>> struct Helper {
>>>>>   void operator()(collapse_t<T> t) {
>>>>>     bar(std::forward<T>(t)); // What do you do here?
>>>>> };
>>>>>
>>>>> template <class T>
>>>>> void foo(T&& t) {
>>>>>   Helper<T>{}(std::forward<T>(t));
>>>>> }
>>>>> =20
>>>>>
>>>>
>>>>
>>>> In this case you are forwarding as a different type. This is the reaso=
n=20
>>>> std::forward will not be deprecated.=20
>>>> And as a nice side effect - we can finally explain to a beginner why=
=20
>>>> does forward need a template argument - to be able to forward as diffe=
rent=20
>>>> type! (a cop out, =E2=80=A6 or may be not)
>>>>
>>>
>>> In that example, I'm not forwarding as a different type. As far as the=
=20
>>> compiler is concerned, I might be, but actually I'm not.
>>>
>>
>> You are building your own type-system. You are forwarding A<B> as B.=20
>>
>> I guess it can be done, we can imagine some interface like begin() end()=
=20
>> for for or get() for structure binding, but these are out of scope.
>>
>
> What I wanted to say: it is currently possible to write that kind of, it=
=20
> should still be possible with what you propose.
>


It might be nice but, I'll not go as far as to say "it should" as reference=
=20
collapsing and casting are language level.=20

All I am doing, I am letting the compiler pick the correct static_cast<>=20
because in my view this is 100% statically deterministic.

If you want extension points - ideas and requirements are welcome. Honestly=
=20
I can't even write the requirements at this point.


Sidenote: yeah, I skimmed over collapse_t. It is not a different type.=20
However you are implementing language level feature with templates.=20
This is the same as how we had move semantics in C++03 (the auto_ptr=20
implementation)

=20

> I don't want such a collapse_t to be in the standard at all. But it is=20
> possible to write it and use it.
> And to some extent (not this particular example), it is used.
> =20
>
>>
>> You can share your concrete needs, might add Future Direction section or=
=20
>> something.=20
>> For now I care about to have language level tools to have "zero overhead=
"=20
>> language level syntax to use them.
>>
>>
> Agreed.
> =20
>
>> =20
>>>
>>>>
>>>>
>>>>  =E2=80=A6...
>>>>
>>>
>>>>
>>>> Besides, given
>>>>
>>>> auto& a =3D geta();
>>>>
>>>> These two would be equivalent.=20
>>>>
>>>> oms(a&&>);
>>>> oms(a);=20
>>>>
>>>
>>> Here, he is being explicit that he doesn't use a after a&&> (despite=20
>>> doing it anyway, but I'm pretty sure you put the second line just for=
=20
>>> comparison).
>>> But the function that returned the reference in the first place might=
=20
>>> need the object in the future. So it shouldn't be implicitly moved. Tha=
t=20
>>> would be dangerous.
>>>
>>> However:
>>> auto&& a =3D geta();
>>> auto b =3D getb();
>>>
>>> oms(a); // will use it afterwards
>>> oms(a&&>); // will not use it afterwards
>>> oms(b&&>); //will not use it afterwards
>>> If a is a rvalue reference, a&&> will correctly move it.
>>> If a happens to be a lvalue reference, it will not be moved, but just=
=20
>>> forwarded as is.
>>>
>>
>>
>>  At the moment &&> will behave EXACTLY as you described.=20
>>
>>
> Exactly in those cases, not in the auto& case. I just wanted to highlight=
=20
> the differences in those cases.
> =20
>
>>
>> =20
>>
>>> As b cannot be a reference (that's how auto works), b will be moved:=20
>>> there is no outside world.
>>>
>>> Now:
>>> auto&& a =3D geta();
>>>
>>> oms(std::move(a));
>>> Will move a even if a is an lvalue reference, even if the object was=20
>>> still needed somewhere else (so to be used with caution).
>>>
>>
>>
>> And this is EXACTLY why move will not be deprecated - to force-cast a=20
>> collapsing reference.=20
>>
>>
>> I am a bit confused.=20
>> I think you think about auto&& to be the type of decltype(a), but I=20
>> think of it as collapsing reference because at it is at that point,=20
>> when it is still a collapsing reference, that the compiler will inject=
=20
>> the correct impl of give. After collapse is way too late, of course.=20
>>
>
> I don't think about auto&& as decltype(a): it is not the same. But this i=
s=20
> irrelevant to my point.
> You want to give a different behavior to auto&& because it collapses=20
> references.
>



But it is different. It is not a type declaration, its a language level=20
template-expression declaration, your collapser_t build-in if you will.
I have full right to treat these as special, as the language already does.


=20

> That's exactly the point I disagree.
> Currently, there is no way to tell when there is reference collapsing. An=
d=20
> that's perfect because it is a tricky, yet useful, feature of C++.
>


After few template processing or argument passing it is lost, yes.=20
But at the top level is clear  - syntax of the form T&& will trigger=20
reference collapsing (if any), and it is always correct to static_cast<T&&>=
=20
to pass it on
In a way that case is the easiest, because the language is already smart=20
about it.

=20

> If you make something behaving differently when there is reference=20
> collapsing and where there isn't, the language will get more confusing.
>


As said, the language already does,  static_cast<T&&> no longer returns=20
rvalue ref (as it "obviously should") - it returns &. yes this is=20
confusing, but that's how it is.

=20

>
> I would expect this:
> using A =3D int&;
> int i =3D 0;
> A&& j =3D i;
> foo(j&&>);
> to stay equivalent to this:
> int i =3D 0;
> int &j =3D i;
> foo(j&&>);
>
> Because in both cases, j have the exact same type.
> With what you propose, they will have different behavior because of the=
=20
> way they are declared while being the same type.
>



Today is not very different. If you forward<int>(j) - it is moved, if=20
forward<A>(j) - it will be forwarded.=20

And comes the question. What is the intend of the user? Does he want to=20
forward a &? Why on earth he even THINKS he can do that?!?

Wasn't he told in school "you forward only forwarding references"?=20
In order to "forward" an & - you MUST pass through reference collapsing.=20
These are the rules today! You must typedef A&& or you must decltype(x) to=
=20
get the exact type.=20

So, with an operator it is obvious what will be done in what case. If the=
=20
user &&> a reference (he sees its an reference, in code), by todays rules,=
=20
this MUST be a move, on another hand, is the type is hidden behind a=20
collapse (he sees its a T&&) - it MUST be forward. =20
(Needless to say, you never want to "forward" a & - as you can just pass=20
the variable as is.)


Sidenote. Probably the example you are looking for:

using A =3D C&;
A j =3D c;
f(std::forward<A>(j));

using A =3D C&;
A&& j =3D c;
f(std::forward<A>(j));

Same today, different with &&>.=20

But as said, it will still be correct (arguably more correct) , as the user=
=20
is explicit what he declares and what he wants.


=20

> And what about:
> using A =3D int&;
> using B =3D A&&;
>
> int i =3D 0;
> B j =3D i;
> foo(j&&>); // shall it be moved?
>
>
Of course not. B is reference collapsing "expression"/"type", reference=20
collapses are AWAYS forwarded. =20
=20

>
> This would be completely new and unusual in the language. This is what I=
=20
> want to avoid.
> The type of the variable alone should be enough to decide what to do. (th=
e=20
> type of the expression is obviously not enough).
>


As said, I am taping on the level before the type of the variable becomes=
=20
finalized. When the auto&& is just an expression to capture the type,=20
whatever it is.

Only at this point, we can have no-brain forward-or-move-you-know-best,=20
because the compiler (preprocessor I guess, because there is no=20
instantiations) has all the information to do the right thing.=20

At type level this can not be solved.=20

=20

> All my examples show you what kind of code would behave differently.
>
> Just to clarify things a bit. If I insist, it is because I really want to=
=20
> help you finding the problems with your approach (Whatever your approach=
=20
> could be).
> While I do prefer my solution, yours is also interesting ;)
>

I am very grateful to you, because with your use cases outside forwarding=
=20
references (as per The Standard) it helped me find the actual valid uses.=
=20
After all both operator()(A&&...) and auto&& var =3D =E2=80=A6 are not  for=
warding=20
references (as per The Standard)=20

--=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/9a9d9d32-f2a2-4925-9b03-002435bfd1d1%40isocpp.or=
g.

------=_Part_98339_1705356792.1528705040327
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, flo=
ria...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><br><br>Le dimanche 10 juin 2018 20:59:45 UTC+2, <a>mihailn...@gm=
ail.com</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>flori=
a...@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"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.=
com</a> 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"><div dir=
=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...=
@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com=
</a> a =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div><br><=
/div><div>But you can always imagine some meta-function that give the same =
result as reference collapsing without relying on reference collapsing, and=
 that being used as a function parameter.</div><div>Reference collapsing is=
 a bit like &quot;forwarding&quot; reference: once it has happened, it shou=
ld behave the same as if never happened in the first place if the types are=
 equals.</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#008">template</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008=
">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">using</span><span style=3D"color:#000"> type </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> collapse</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&=
amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">using</sp=
an><span style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> collapse</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> ty=
pe </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
><code><span style=3D"color:#000"><br></span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">* &gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">using</span><span style=3D"color:#000">=
 type </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
></span></code></span><span style=3D"color:#000"><code><span style=3D"color=
:#000"><code><span style=3D"color:#800"> // Optimization for trivial types =
</span><span style=3D"color:#000"><br></span></code></span></code></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">using</span>=
<span style=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>typename</span><span style=3D"color:#000"> collapse</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"col=
or:#660">&gt;::</span><span style=3D"color:#000">type</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br><br><br></span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</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">struct</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Helper</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">operator</spa=
n><span style=3D"color:#660">()(</span><span style=3D"color:#000">collapse_=
t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> t</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 bar</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">forward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#=
000">t</span><span style=3D"color:#660">));</span><span style=3D"color:#000=
"> </span><span style=3D"color:#800">// What do you do here?</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span sty=
le=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><s=
pan 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:#660">(</span><span style=3D"color:#000">T</span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span>=
<span style=3D"color:#606">Helper</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</=
span><span style=3D"color:#000">t</span><span style=3D"color:#660">)<wbr>);=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"></span><br></div></code></div></div><div>=
=C2=A0</div></div></blockquote><div><br></div><div><br></div><div>In this c=
ase you are forwarding as a different type. This is the reason std::forward=
 will not be deprecated.=C2=A0</div><div>And as a nice side effect - we can=
 finally explain to a beginner why does forward need a template argument - =
to be able to forward as different type! (a cop out, =E2=80=A6 or may be no=
t)</div></div></blockquote><div><br></div><div>In that example, I&#39;m not=
 forwarding as a different type. As far as the compiler is concerned, I mig=
ht be, but actually I&#39;m not.<br></div></div></blockquote><div><br></div=
><div>You are building your own type-system. <span style=3D"display:inline!=
important;float:none;background-color:transparent;color:rgb(34,34,34);font-=
family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;fo=
nt-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;t=
ext-align:left;text-decoration:none;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px">You are forwarding A&lt;B&gt; as B.=C2=A0=
</span><br></div><div><br></div><div>I guess it can be done, we can imagine=
 some interface like begin() end() for for or get() for structure binding, =
but these are out of scope.</div></div></blockquote><div><br></div><div>Wha=
t I wanted to say: it is currently possible to write that kind of, it shoul=
d still be possible with what you propose.</div></div></blockquote><div><br=
></div><div><br></div><div>It might be nice but, I&#39;ll not go as far as =
to say &quot;it should&quot; as reference collapsing and casting are langua=
ge level.=C2=A0</div><div><br></div><div>All I am doing, I am letting the c=
ompiler pick the correct static_cast&lt;&gt; because in my view this is 100=
% statically deterministic.</div><div><br></div><div>If you want extension =
points - ideas and requirements are welcome. Honestly I can&#39;t even writ=
e the requirements at this point.</div><div><br></div><div><br></div><div>S=
idenote: yeah, I skimmed over collapse_t. It is not a different type. Howev=
er you are implementing language level feature with templates. <br>This is =
the same as how we had move semantics in C++03 (the auto_ptr implementation=
)</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div>I don&#39;t want such a collapse_t to be in =
the standard at all. But it is possible to write it and use it.</div><div>A=
nd to some extent (not this particular example), it is used.<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><div>You can share your concrete needs, might add Future Direction=
 section or something.=C2=A0</div><div>For now I care about to have languag=
e level tools to have &quot;zero overhead&quot; language level syntax to us=
e them.</div><div><br></div></div></blockquote><div><br></div><div>Agreed.<=
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></div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div><br></div><div><br></div><div>=C2=A0=E2=80=A6...</div></di=
v></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><di=
v><br></div><div><br></div><div>Besides, given</div><div><br></div><div><fo=
nt face=3D"courier new,monospace">auto&amp; a =3D geta();</font></div><div>=
<font face=3D"courier new,monospace"><br></font></div><div>These two would =
be equivalent.=C2=A0</div><div><br></div><div><font face=3D"courier new,mon=
ospace">oms(a&amp;&amp;&gt;);</font></div><div><font face=3D"courier new,mo=
nospace">oms(a);=C2=A0</font></div></div></blockquote><div><br></div><div>H=
ere, he is being explicit that he doesn&#39;t use <span style=3D"font-famil=
y:courier new,monospace">a</span> after <span style=3D"font-family:courier =
new,monospace">a&amp;&amp;&gt;</span> (despite doing it anyway, but I&#39;m=
 pretty sure you put the second line just for comparison).</div><div>But th=
e function that returned the reference in the first place might need the ob=
ject in the future. So it shouldn&#39;t be implicitly moved. That would be =
dangerous.<br></div><div><br></div><div>However:</div><div><div style=3D"ba=
ckground-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</span><s=
pan style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> a </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> geta</=
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"> b </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> getb<=
/span><span style=3D"color:#660">();</span><span style=3D"color:#000"><br><=
br>oms</span><span style=3D"color:#660">(</span><span style=3D"color:#000">=
a</span><span style=3D"color:#660">);</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#800">// will use it afterwards</span><span style=
=3D"color:#000"><br>oms</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">a</span><span style=3D"color:#660">&amp;&amp;&gt;);</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#800">// will not u=
se it afterwards</span><span style=3D"color:#000"><br>oms</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">b</span><span style=3D"c=
olor:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </span><span =
style=3D"color:#800">//will not use it afterwards</span><span style=3D"colo=
r:#000"><br></span></div></code></div></div><div>If <span style=3D"font-fam=
ily:courier new,monospace">a</span> is a rvalue reference, <span style=3D"f=
ont-family:courier new,monospace">a&amp;&amp;&gt;</span> will correctly mov=
e it.</div><div>If <span style=3D"font-family:courier new,monospace">a</spa=
n> happens to be a lvalue reference, it will not be moved, but just forward=
ed as is.</div></div></blockquote><div><br></div><div><br></div><div>=C2=A0=
At the moment &amp;&amp;&gt; will behave EXACTLY as you described.=C2=A0</d=
iv><div><br></div></div></blockquote><div><br></div><div>Exactly in those c=
ases, not in the <span style=3D"font-family:courier new,monospace">auto&amp=
;</span> case. I just wanted to highlight the differences in those cases.<b=
r></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></div><div><br></div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>As <span style=3D"font-family:courie=
r new,monospace">b</span> cannot be a reference (that&#39;s how auto works)=
, <span style=3D"font-family:courier new,monospace">b</span> will be moved:=
 there is no outside world.<br></div><div><br></div><div>Now:</div><div><di=
v 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</span><span style=3D"color:#660">&amp;&amp;</span><span style=3D"color=
:#000"> a </span><span style=3D"color:#660">=3D</span><span style=3D"color:=
#000"> geta</span><span style=3D"color:#660">();</span><span style=3D"color=
:#000"><br><br>oms</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">std</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">move</span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#000">a</span><span style=3D"color:#660">));</span><span style=3D"color:#=
000"><br></span></div></code></div>Will move <span style=3D"font-family:cou=
rier new,monospace">a</span> even if <span style=3D"font-family:courier new=
,monospace">a</span> is an lvalue reference, even if the object was still n=
eeded somewhere else (so to be used with caution).<br></div></div></blockqu=
ote><div><br></div><div><br></div><div>And this is EXACTLY why move will no=
t be deprecated - to force-cast a collapsing reference.=C2=A0</div><div><br=
></div><div><br></div><div>I am a bit confused.=C2=A0</div><div>I think you=
 think about <font face=3D"courier new,monospace">auto&amp;&amp;</font> to =
be the type of <font face=3D"courier new,monospace">decltype(a), <font face=
=3D"arial,sans-serif">but I think of it as collapsing reference because at =
it is at that point,=C2=A0</font></font></div><div><font face=3D"courier ne=
w,monospace"><font face=3D"arial,sans-serif">when it is still a collapsing =
reference, that the compiler will inject the correct impl of give. After co=
llapse is way too late, of course.=C2=A0</font></font></div></div></blockqu=
ote><div><br></div><div>I don&#39;t think about auto&amp;&amp; as decltype(=
a): it is not the same. But this is irrelevant to my point.</div><div>You w=
ant to give a different behavior to auto&amp;&amp; because it collapses ref=
erences.</div></div></blockquote><div><br></div><div><br></div><div><br>But=
 it is different. It is not a type declaration, its a language level templa=
te-expression declaration, your collapser_t build-in if you will.</div><div=
>I have full right to treat these as special, as the language already does.=
</div><div><br></div><div><br></div><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>That&#39;s exactly the point I=
 disagree.</div><div>Currently, there is no way to tell when there is refer=
ence collapsing. And that&#39;s perfect because it is a tricky, yet useful,=
 feature of C++.</div></div></blockquote><div><br></div><div><br></div><div=
>After few template processing or argument passing it is lost, yes. </div><=
div>But at the top level is clear=C2=A0 - syntax of the form T&amp;&amp; wi=
ll trigger reference collapsing (if any), and it is always correct to stati=
c_cast&lt;T&amp;&amp;&gt; to pass it on</div><div>In a way that case is the=
 easiest, because the language is already smart about it.<br></div><div><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 d=
ir=3D"ltr"><div>If you make something behaving differently when there is re=
ference collapsing and where there isn&#39;t, the language will get more co=
nfusing.</div></div></blockquote><div><br></div><div><br></div><div>As said=
, the language already does,=C2=A0 static_cast&lt;T&amp;&amp;&gt; no longer=
 returns rvalue ref (as it &quot;obviously should&quot;) - it returns &amp;=
.. yes this is confusing, but that&#39;s how it is.<br></div><div><br></div>=
<div>=C2=A0</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"l=
tr"><div><br></div><div>I would expect this:</div><div><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px"><code><div><span style=3D"color:#008">using</span><span=
 style=3D"color:#000"> A </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#660">&amp;;</span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">int</span><span style=3D"color:#000"> i </span><span s=
tyle=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"><br>A</span><span style=3D"color:#660">&amp;&amp;</span><span s=
tyle=3D"color:#000"> j </span><span style=3D"color:#660">=3D</span><span st=
yle=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>foo</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt;);</span>=
<span style=3D"color:#000"><br></span></div></code></div>to stay equivalent=
 to this:</div><div><div style=3D"background-color:rgb(250,250,250);border-=
color:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><spa=
n style=3D"color:#008">int</span><span style=3D"color:#000"> i </span><span=
 style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">int</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><span style=
=3D"color:#000">j </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span style=3D"=
color:#000"><br>foo</span><span style=3D"color:#660">(</span><span style=3D=
"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><spa=
n style=3D"color:#000"><br></span></div></code></div></div><div><br></div><=
div>Because in both cases, j have the exact same type.</div><div>With what =
you propose, they will have different behavior because of the way they are =
declared while being the same type.</div></div></blockquote><div><br></div>=
<div><br></div><div><br>Today is not very different. If you forward&lt;int&=
gt;(j) - it is moved, if forward&lt;A&gt;(j) - it will be forwarded.=C2=A0<=
/div><div><br></div><div>And comes the question. What is the intend of the =
user? Does he want to forward a &amp;? Why on earth he even THINKS he can d=
o that?!?</div><div><br></div><div>Wasn&#39;t he told in school &quot;you f=
orward only forwarding references&quot;? </div><div>In order to &quot;forwa=
rd&quot; an &amp; - you MUST pass through reference collapsing. These are t=
he rules today! You must typedef A&amp;&amp; or you must decltype(x) to get=
 the exact type. </div><div><br></div><div>So, with an operator it is obvio=
us what will be done in what case. If the user &amp;&amp;&gt; a reference (=
he sees its an reference, in code), by todays rules, this MUST be a move, o=
n another hand, is the type is hidden behind a collapse (he sees its a T&am=
p;&amp;) - it MUST be forward. =C2=A0<br></div><div>(Needless to say, you n=
ever want to &quot;forward&quot; a &amp; - as you can just pass the variabl=
e as is.)</div><div><br></div><div><br>Sidenote. Probably the example you a=
re looking for:</div><div><br></div><div><font face=3D"courier new,monospac=
e">using A =3D C&amp;;<br>A j =3D c;<br>f(std::forward&lt;A&gt;(j));</font>=
</div><div><font face=3D"courier new,monospace"><br></font></div><div><font=
 face=3D"courier new,monospace">using A =3D C&amp;;<br>A&amp;&amp; j =3D c;=
<br>f(std::forward&lt;A&gt;(j));</font></div><div><font face=3D"courier new=
,monospace"><br></font></div><div>Same today, different with &amp;&amp;&gt;=
..=C2=A0</div><div><br></div><div>But as said, it will still be correct (arg=
uably more correct) , as the user is explicit what he declares and what he =
wants.<br></div><div><br></div><div><br></div><div>=C2=A0</div><blockquote =
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>And what about:</div=
><div><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"col=
or:#008">using</span><span style=3D"color:#000"> A </span><span style=3D"co=
lor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">int</span><span style=3D"color:#660">&amp;;</span><span style=3D"col=
or:#000"><br></span><span style=3D"color:#008">using</span><span style=3D"c=
olor:#000"> B </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> A</span><span style=3D"color:#660">&amp;&amp;;</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">int</span><span s=
tyle=3D"color:#000"> i </span><span style=3D"color:#660">=3D</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#066">0</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br>B j </span><span sty=
le=3D"color:#660">=3D</span><span style=3D"color:#000"> i</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">j</span><span style=3D"=
color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#800">// shall it be moved?</span><span style=3D"color:#000=
"><br></span></div></code></div><br></div></div></blockquote><div><br></div=
><div>Of course not. B is reference collapsing &quot;expression&quot;/&quot=
;type&quot;, reference collapses are AWAYS forwarded.=C2=A0 <br></div><div>=
=C2=A0</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><br></div><div>This would be completely new and unusual in the language=
.. This is what I want to avoid.</div><div>The type of the variable alone sh=
ould be enough to decide what to do. (the type of the expression is obvious=
ly not enough).</div></div></blockquote><div><br></div><div><br></div><div>=
As said, I am taping on the level before the type of the variable becomes f=
inalized. When the auto&amp;&amp; is just an expression to capture the type=
, whatever it is.</div><div><br></div><div>Only at this point, we can have =
no-brain forward-or-move-you-know-best, because the compiler (preprocessor =
I guess, because there is no instantiations) has all the information to do =
the right thing.=C2=A0</div><div><br></div><div>At type level this can not =
be solved. <br></div><div><br></div><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>All my examples show you what =
kind of code would behave differently.<br></div><div><br></div><div>Just to=
 clarify things a bit. If I insist, it is because I really want to help you=
 finding the problems with your approach (Whatever your approach could be).=
</div><div>While I do prefer my solution, yours is also interesting ;)<br><=
/div></div></blockquote><div><br></div><div>I am very grateful to you, beca=
use with your use cases outside forwarding references (as per The Standard)=
 it helped me find the actual valid uses. After all both operator()(A&amp;&=
amp;...) and auto&amp;&amp; var =3D =E2=80=A6 are not=C2=A0 forwarding refe=
rences (as per The Standard)=C2=A0</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/9a9d9d32-f2a2-4925-9b03-002435bfd1d1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9a9d9d32-f2a2-4925-9b03-002435bfd1d1=
%40isocpp.org</a>.<br />

------=_Part_98339_1705356792.1528705040327--

------=_Part_98338_1869311901.1528705040325--

.


Author: florian.csdt@gmail.com
Date: Mon, 11 Jun 2018 02:00:34 -0700 (PDT)
Raw View
------=_Part_4001_251565175.1528707634762
Content-Type: multipart/alternative;
 boundary="----=_Part_4002_1936582330.1528707634763"

------=_Part_4002_1936582330.1528707634763
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



Le lundi 11 juin 2018 10:17:20 UTC+2, mihailn...@gmail.com a =C3=A9crit :
>
>
>
> On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, floria...@gmail.com wrote:
>>
>>
>>
>> Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn...@gmail.com a =C3=A9cr=
it :
>>>
>>>
>>>
>>> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com wrote=
:
>>>>
>>>>
>>>>
>>>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a =C3=A9=
crit :
>>>>>
>>>>>
>>>>>
>>>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com=20
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a=20
>>>>>> =C3=A9crit :
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=
=20
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=20
>>>>>>>> =C3=A9crit :...
>>>>>>>>
>>>>>>>
>>>>>> But you can always imagine some meta-function that give the same=20
>>>>>> result as reference collapsing without relying on reference collapsi=
ng, and=20
>>>>>> that being used as a function parameter.
>>>>>> Reference collapsing is a bit like "forwarding" reference: once it=
=20
>>>>>> has happened, it should behave the same as if never happened in the =
first=20
>>>>>> place if the types are equals.
>>>>>>
>>>>>> template <class T> struct collapse      { using type =3D T&&; };
>>>>>> template <class T> struct collapse<T& > { using type =3D T& ; };
>>>>>> template <class T> struct collapse<T&&> { using type =3D T&&; };
>>>>>> template <class T> struct collapse<T* > { using type =3D T  ; }; //=
=20
>>>>>> Optimization for trivial types=20
>>>>>> template <class T> using  collapse_t =3D typename collapse<T>::type;
>>>>>>
>>>>>>
>>>>>> template <class T>
>>>>>> struct Helper {
>>>>>>   void operator()(collapse_t<T> t) {
>>>>>>     bar(std::forward<T>(t)); // What do you do here?
>>>>>> };
>>>>>>
>>>>>> template <class T>
>>>>>> void foo(T&& t) {
>>>>>>   Helper<T>{}(std::forward<T>(t));
>>>>>> }
>>>>>> =20
>>>>>>
>>>>>
>>>>>
>>>>> In this case you are forwarding as a different type. This is the=20
>>>>> reason std::forward will not be deprecated.=20
>>>>> And as a nice side effect - we can finally explain to a beginner why=
=20
>>>>> does forward need a template argument - to be able to forward as diff=
erent=20
>>>>> type! (a cop out, =E2=80=A6 or may be not)
>>>>>
>>>>
>>>> In that example, I'm not forwarding as a different type. As far as the=
=20
>>>> compiler is concerned, I might be, but actually I'm not.
>>>>
>>>
>>> You are building your own type-system. You are forwarding A<B> as B.=20
>>>
>>> I guess it can be done, we can imagine some interface like begin() end(=
)=20
>>> for for or get() for structure binding, but these are out of scope.
>>>
>>
>> What I wanted to say: it is currently possible to write that kind of, it=
=20
>> should still be possible with what you propose.
>>
>
>
> It might be nice but, I'll not go as far as to say "it should" as=20
> reference collapsing and casting are language level.=20
>
> All I am doing, I am letting the compiler pick the correct static_cast<>=
=20
> because in my view this is 100% statically deterministic.
>
> If you want extension points - ideas and requirements are welcome.=20
> Honestly I can't even write the requirements at this point.
>
>
> Sidenote: yeah, I skimmed over collapse_t. It is not a different type.=20
> However you are implementing language level feature with templates.=20
> This is the same as how we had move semantics in C++03 (the auto_ptr=20
> implementation)
>

Yes, I am. But this is very common practice in template metaprogramming.
=20

>
> =20
>
>> I don't want such a collapse_t to be in the standard at all. But it is=
=20
>> possible to write it and use it.
>> And to some extent (not this particular example), it is used.
>> =20
>>
>>>
>>> You can share your concrete needs, might add Future Direction section o=
r=20
>>> something.=20
>>> For now I care about to have language level tools to have "zero=20
>>> overhead" language level syntax to use them.
>>>
>>>
>> Agreed.
>> =20
>>
>>> =20
>>>>
>>>>>
>>>>>
>>>>>  =E2=80=A6...
>>>>>
>>>>
>>>>>
>>>>> Besides, given
>>>>>
>>>>> auto& a =3D geta();
>>>>>
>>>>> These two would be equivalent.=20
>>>>>
>>>>> oms(a&&>);
>>>>> oms(a);=20
>>>>>
>>>>
>>>> Here, he is being explicit that he doesn't use a after a&&> (despite=
=20
>>>> doing it anyway, but I'm pretty sure you put the second line just for=
=20
>>>> comparison).
>>>> But the function that returned the reference in the first place might=
=20
>>>> need the object in the future. So it shouldn't be implicitly moved. Th=
at=20
>>>> would be dangerous.
>>>>
>>>> However:
>>>> auto&& a =3D geta();
>>>> auto b =3D getb();
>>>>
>>>> oms(a); // will use it afterwards
>>>> oms(a&&>); // will not use it afterwards
>>>> oms(b&&>); //will not use it afterwards
>>>> If a is a rvalue reference, a&&> will correctly move it.
>>>> If a happens to be a lvalue reference, it will not be moved, but just=
=20
>>>> forwarded as is.
>>>>
>>>
>>>
>>>  At the moment &&> will behave EXACTLY as you described.=20
>>>
>>>
>> Exactly in those cases, not in the auto& case. I just wanted to=20
>> highlight the differences in those cases.
>> =20
>>
>>>
>>> =20
>>>
>>>> As b cannot be a reference (that's how auto works), b will be moved:=
=20
>>>> there is no outside world.
>>>>
>>>> Now:
>>>> auto&& a =3D geta();
>>>>
>>>> oms(std::move(a));
>>>> Will move a even if a is an lvalue reference, even if the object was=
=20
>>>> still needed somewhere else (so to be used with caution).
>>>>
>>>
>>>
>>> And this is EXACTLY why move will not be deprecated - to force-cast a=
=20
>>> collapsing reference.=20
>>>
>>>
>>> I am a bit confused.=20
>>> I think you think about auto&& to be the type of decltype(a), but I=20
>>> think of it as collapsing reference because at it is at that point,=20
>>> when it is still a collapsing reference, that the compiler will inject=
=20
>>> the correct impl of give. After collapse is way too late, of course.=20
>>>
>>
>> I don't think about auto&& as decltype(a): it is not the same. But this=
=20
>> is irrelevant to my point.
>> You want to give a different behavior to auto&& because it collapses=20
>> references.
>>
>
>
>
> But it is different. It is not a type declaration, its a language level=
=20
> template-expression declaration, your collapser_t build-in if you will.
> I have full right to treat these as special, as the language already does=
..
>
>
You have the right to treat these as special. My question is (and was=20
always): should you? Would it make sense? Would it create some nasty=20
problems we want to avoid?
=20

>
> =20
>
>> That's exactly the point I disagree.
>> Currently, there is no way to tell when there is reference collapsing.=
=20
>> And that's perfect because it is a tricky, yet useful, feature of C++.
>>
>
>
> After few template processing or argument passing it is lost, yes.=20
> But at the top level is clear  - syntax of the form T&& will trigger=20
> reference collapsing (if any), and it is always correct to static_cast<T&=
&>=20
> to pass it on
> In a way that case is the easiest, because the language is already smart=
=20
> about it.
>

You just said it: at the top level. In most template metaprograms, the=20
top-level part is completely buried "under" several levels of indirection.
And forwarding must work from the top level to the deepest level and give=
=20
the exact same result. Because it makes it easy to think about the code.
If &&> works differently at the top level than at the other levels, then I=
=20
have the feeling it will create more problems that solving.
=20

>
> =20
>
>> If you make something behaving differently when there is reference=20
>> collapsing and where there isn't, the language will get more confusing.
>>
>
>
> As said, the language already does,  static_cast<T&&> no longer returns=
=20
> rvalue ref (as it "obviously should") - it returns &. yes this is=20
> confusing, but that's how it is.
>
>
Because static_cast doesn't care about reference collapsing: it sees a type=
=20
and use it. This type might have been collapsed, it doesn't change the=20
result.
=20

> =20
>
>>
>> I would expect this:
>> using A =3D int&;
>> int i =3D 0;
>> A&& j =3D i;
>> foo(j&&>);
>> to stay equivalent to this:
>> int i =3D 0;
>> int &j =3D i;
>> foo(j&&>);
>>
>> Because in both cases, j have the exact same type.
>> With what you propose, they will have different behavior because of the=
=20
>> way they are declared while being the same type.
>>
>
>
>
> Today is not very different. If you forward<int>(j) - it is moved, if=20
> forward<A>(j) - it will be forwarded.=20
>
> And comes the question. What is the intend of the user? Does he want to=
=20
> forward a &? Why on earth he even THINKS he can do that?!?
>
> Wasn't he told in school "you forward only forwarding references"?=20
> In order to "forward" an & - you MUST pass through reference collapsing.=
=20
> These are the rules today! You must typedef A&& or you must decltype(x) t=
o=20
> get the exact type.=20
>

Those are not the today rules. If you want to forward a lvalue ref, just=20
pass it. If you cannot know if it is a lvalue or a rvalue ref, then you use=
=20
std::forward. If you want to forward a rvalue reference, you use std::move.
These are the today rules.
=20

>
> So, with an operator it is obvious what will be done in what case. If the=
=20
> user &&> a reference (he sees its an reference, in code), by todays rules=
,=20
> this MUST be a move, on another hand, is the type is hidden behind a=20
> collapse (he sees its a T&&) - it MUST be forward. =20
> (Needless to say, you never want to "forward" a & - as you can just pass=
=20
> the variable as is.)
>
>
> Sidenote. Probably the example you are looking for:
>
> using A =3D C&;
> A j =3D c;
> f(std::forward<A>(j));
>
> using A =3D C&;
> A&& j =3D c;
> f(std::forward<A>(j));
>
> Same today, different with &&>.=20
>
> But as said, it will still be correct (arguably more correct) , as the=20
> user is explicit what he declares and what he wants.
>

That's actually what I want. Because in practice, there will be many cases=
=20
where A is not known by the user but just given by something else.
And if A and A&& are the same type, they should behave the same. But here=
=20
it won't.
=20

>
>
> =20
>
>> And what about:
>> using A =3D int&;
>> using B =3D A&&;
>>
>> int i =3D 0;
>> B j =3D i;
>> foo(j&&>); // shall it be moved?
>>
>>
> Of course not. B is reference collapsing "expression"/"type", reference=
=20
> collapses are AWAYS forwarded. =20
>

And if B is not defined just above but given by a template parameter?
template <class T> void bar(T&&);
template <class T> void foo(T t) { bar(t&&>); }

using A =3D int&;
using B =3D int&&;

int i =3D 0, j =3D 0;
A I =3D i;
B J =3D j;
foo<A>(I); // call foo<int&>() -> bar<int&&>()
foo<B>(J); // call foo<int&>() -> bar<int??>()

bar(I&&>); // call bar<int&&>()
bar(J&&>); // call bar<int&>()
Should the two calls to foo behave the same, I bet so.
But B was collapsed where A was not.

And now, by introducing a wrapper, either the meaning of the code has=20
changed (if foo<B>(J) calls bar<int&&>()) or you need to differentiate the=
=20
2 calls to foo disambiguation with something that is not encoded in the=20
type (and then generates 2 symbols).
None is satisfying to me.
What you probably want in the end is: "forwarding/universal" references=20
being part of the type system. Or similarly, encode in the type that=20
references has been collapsed making A and B from the example two distinct=
=20
types with the exact same properties.
The first might be feasible but would need big effort to standardize.
The second is completely out of question: A and B would create different=20
types when passed in template parameters. (std::is_same<A, B> would be=20
false...)

Or maybe you're fine with wrapping some code can change the meaning of the=
=20
code. But I'm definitely not.

=20

> =20
>
>>
>> This would be completely new and unusual in the language. This is what I=
=20
>> want to avoid.
>> The type of the variable alone should be enough to decide what to do.=20
>> (the type of the expression is obviously not enough).
>>
>
>
> As said, I am taping on the level before the type of the variable becomes=
=20
> finalized. When the auto&& is just an expression to capture the type,=20
> whatever it is.
>
> Only at this point, we can have no-brain forward-or-move-you-know-best,=
=20
> because the compiler (preprocessor I guess, because there is no=20
> instantiations) has all the information to do the right thing.=20
>
> At type level this can not be solved.=20
>
>
But the type system is the only part of the language you can reliably use=
=20
to build your operator if you want to avoid the problems I mentioned=20
earlier.
You're completely right saying the compiler has all the information to do=
=20
the right thing, but only at the top level. But we also want this to work=
=20
with deeper levels. Because that's what is used in template metapgrograms.
=20

> =20
>
>> All my examples show you what kind of code would behave differently.
>>
>> Just to clarify things a bit. If I insist, it is because I really want t=
o=20
>> help you finding the problems with your approach (Whatever your approach=
=20
>> could be).
>> While I do prefer my solution, yours is also interesting ;)
>>
>
> I am very grateful to you, because with your use cases outside forwarding=
=20
> references (as per The Standard) it helped me find the actual valid uses.=
=20
> After all both operator()(A&&...) and auto&& var =3D =E2=80=A6 are not  f=
orwarding=20
> references (as per The Standard)=20
>

--=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/f955ea1c-7cbf-4077-96b4-fd00b110b0f3%40isocpp.or=
g.

------=_Part_4002_1936582330.1528707634763
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>Le lundi 11 juin 2018 10:17:20 UTC+2, mihailn...@g=
mail.com a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, <a>fl=
oria...@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 20:59:45 UTC+2, <a>mihailn...@gm=
ail.com</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>flori=
a...@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"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gma=
il.com</a> a =C3=A9crit=C2=A0:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.=
com</a> 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"><div dir=
=3D"ltr"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...=
@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com=
</a> a =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div><br><=
/div><div>But you can always imagine some meta-function that give the same =
result as reference collapsing without relying on reference collapsing, and=
 that being used as a function parameter.</div><div>Reference collapsing is=
 a bit like &quot;forwarding&quot; reference: once it has happened, it shou=
ld behave the same as if never happened in the first place if the types are=
 equals.</div><div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><=
code><div><span style=3D"color:#008">template</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008=
">class</span><span style=3D"color:#000"> T</span><span style=3D"color:#660=
">&gt;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">=
struct</span><span style=3D"color:#000"> collapse =C2=A0 =C2=A0 =C2=A0</spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">using</span><span style=3D"color:#000"> type </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">template</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class=
</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> collapse</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#000">T</span><span style=3D"color:#660">&=
amp;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">using</sp=
an><span style=3D"color:#000"> type </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&amp;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">;</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><=
span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#008">struct</span><span style=3D"color:#000"> collapse</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T</sp=
an><span style=3D"color:#660">&amp;&amp;&gt;</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#008">using</span><span style=3D"color:#000"> ty=
pe </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
T</span><span style=3D"color:#660">&amp;&amp;;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
><code><span style=3D"color:#000"><br></span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#008">class</span><span style=3D"color:#000"=
> T</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
 </span><span style=3D"color:#008">struct</span><span style=3D"color:#000">=
 collapse</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">* &gt;</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">using</span><span style=3D"color:#000">=
 type </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> T</span><span style=3D"color:#660">=C2=A0 ;</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"=
></span></code></span><span style=3D"color:#000"><code><span style=3D"color=
:#000"><code><span style=3D"color:#800"> // Optimization for trivial types =
</span><span style=3D"color:#000"><br></span></code></span></code></span><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">using</span>=
<span style=3D"color:#000"> =C2=A0collapse_t </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>typename</span><span style=3D"color:#000"> collapse</span><span style=3D"c=
olor:#660">&lt;</span><span style=3D"color:#000">T</span><span style=3D"col=
or:#660">&gt;::</span><span style=3D"color:#000">type</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br><br><br></span><span sty=
le=3D"color:#008">template</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">&lt;</span><span style=3D"color:#008">class</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">struct</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#606">Helper</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span st=
yle=3D"color:#000"><br>=C2=A0 </span><span style=3D"color:#008">void</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">operator</spa=
n><span style=3D"color:#660">()(</span><span style=3D"color:#000">collapse_=
t</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">T<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> t</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 bar</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">forward</span><span style=3D"color:#660">&lt;</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#=
000">t</span><span style=3D"color:#660">));</span><span style=3D"color:#000=
"> </span><span style=3D"color:#800">// What do you do here?</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span sty=
le=3D"color:#000"><br><br></span><span style=3D"color:#008">template</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><s=
pan style=3D"color:#008">class</span><span style=3D"color:#000"> T</span><s=
pan 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:#660">(</span><span style=3D"color:#000">T</span><span=
 style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> t</span>=
<span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span>=
<span style=3D"color:#606">Helper</span><span style=3D"color:#660">&lt;</sp=
an><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;{}(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">forward</span><span style=3D"color:#660">&lt;<=
/span><span style=3D"color:#000">T</span><span style=3D"color:#660">&gt;(</=
span><span style=3D"color:#000">t</span><span style=3D"color:#660">)<wbr>);=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</=
span><span style=3D"color:#000"></span><br></div></code></div></div><div>=
=C2=A0</div></div></blockquote><div><br></div><div><br></div><div>In this c=
ase you are forwarding as a different type. This is the reason std::forward=
 will not be deprecated.=C2=A0</div><div>And as a nice side effect - we can=
 finally explain to a beginner why does forward need a template argument - =
to be able to forward as different type! (a cop out, =E2=80=A6 or may be no=
t)</div></div></blockquote><div><br></div><div>In that example, I&#39;m not=
 forwarding as a different type. As far as the compiler is concerned, I mig=
ht be, but actually I&#39;m not.<br></div></div></blockquote><div><br></div=
><div>You are building your own type-system. <span style=3D"display:inline!=
important;float:none;background-color:transparent;color:rgb(34,34,34);font-=
family:&quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;fo=
nt-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;t=
ext-align:left;text-decoration:none;text-indent:0px;text-transform:none;whi=
te-space:normal;word-spacing:0px">You are forwarding A&lt;B&gt; as B.=C2=A0=
</span><br></div><div><br></div><div>I guess it can be done, we can imagine=
 some interface like begin() end() for for or get() for structure binding, =
but these are out of scope.</div></div></blockquote><div><br></div><div>Wha=
t I wanted to say: it is currently possible to write that kind of, it shoul=
d still be possible with what you propose.</div></div></blockquote><div><br=
></div><div><br></div><div>It might be nice but, I&#39;ll not go as far as =
to say &quot;it should&quot; as reference collapsing and casting are langua=
ge level.=C2=A0</div><div><br></div><div>All I am doing, I am letting the c=
ompiler pick the correct static_cast&lt;&gt; because in my view this is 100=
% statically deterministic.</div><div><br></div><div>If you want extension =
points - ideas and requirements are welcome. Honestly I can&#39;t even writ=
e the requirements at this point.</div><div><br></div><div><br></div><div>S=
idenote: yeah, I skimmed over collapse_t. It is not a different type. Howev=
er you are implementing language level feature with templates. <br>This is =
the same as how we had move semantics in C++03 (the auto_ptr implementation=
)</div></div></blockquote><div><br></div><div>Yes, I am. But this is very c=
ommon practice in template metaprogramming.<br></div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><di=
v>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
>I don&#39;t want such a collapse_t to be in the standard at all. But it is=
 possible to write it and use it.</div><div>And to some extent (not this pa=
rticular example), it is used.<br></div><div>=C2=A0</div><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><br></div><div>You can share y=
our concrete needs, might add Future Direction section or something.=C2=A0<=
/div><div>For now I care about to have language level tools to have &quot;z=
ero overhead&quot; language level syntax to use them.</div><div><br></div><=
/div></blockquote><div><br></div><div>Agreed.<br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></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></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></div><di=
v><br></div><div>=C2=A0=E2=80=A6...</div></div></blockquote><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><br></div><div><br></div><di=
v>Besides, given</div><div><br></div><div><font face=3D"courier new,monospa=
ce">auto&amp; a =3D geta();</font></div><div><font face=3D"courier new,mono=
space"><br></font></div><div>These two would be equivalent.=C2=A0</div><div=
><br></div><div><font face=3D"courier new,monospace">oms(a&amp;&amp;&gt;);<=
/font></div><div><font face=3D"courier new,monospace">oms(a);=C2=A0</font><=
/div></div></blockquote><div><br></div><div>Here, he is being explicit that=
 he doesn&#39;t use <span style=3D"font-family:courier new,monospace">a</sp=
an> after <span style=3D"font-family:courier new,monospace">a&amp;&amp;&gt;=
</span> (despite doing it anyway, but I&#39;m pretty sure you put the secon=
d line just for comparison).</div><div>But the function that returned the r=
eference in the first place might need the object in the future. So it shou=
ldn&#39;t be implicitly moved. That would be dangerous.<br></div><div><br><=
/div><div>However:</div><div><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</span><span style=3D"color:#660">&amp;=
&amp;</span><span style=3D"color:#000"> a </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> geta</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"> b </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> getb</span><span style=3D"color:#66=
0">();</span><span style=3D"color:#000"><br><br>oms</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">a</span><span style=3D"color:#=
660">);</span><span style=3D"color:#000"> </span><span style=3D"color:#800"=
>// will use it afterwards</span><span style=3D"color:#000"><br>oms</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">a</span><span =
style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#800">// will not use it afterwards</span><span st=
yle=3D"color:#000"><br>oms</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">b</span><span style=3D"color:#660">&amp;&amp;&gt;);</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#800">//will not=
 use it afterwards</span><span style=3D"color:#000"><br></span></div></code=
></div></div><div>If <span style=3D"font-family:courier new,monospace">a</s=
pan> is a rvalue reference, <span style=3D"font-family:courier new,monospac=
e">a&amp;&amp;&gt;</span> will correctly move it.</div><div>If <span style=
=3D"font-family:courier new,monospace">a</span> happens to be a lvalue refe=
rence, it will not be moved, but just forwarded as is.</div></div></blockqu=
ote><div><br></div><div><br></div><div>=C2=A0At the moment &amp;&amp;&gt; w=
ill behave EXACTLY as you described.=C2=A0</div><div><br></div></div></bloc=
kquote><div><br></div><div>Exactly in those cases, not in the <span style=
=3D"font-family:courier new,monospace">auto&amp;</span> case. I just wanted=
 to highlight the differences in those cases.<br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div><br><=
/div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>As <span style=3D"font-family:courier new,monospace">b</span> cann=
ot be a reference (that&#39;s how auto works), <span style=3D"font-family:c=
ourier new,monospace">b</span> will be moved: there is no outside world.<br=
></div><div><br></div><div>Now:</div><div><div style=3D"background-color:rg=
b(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-widt=
h:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#660">&amp;&amp;</span><span style=3D"color:#000"> a </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> geta</span><span styl=
e=3D"color:#660">();</span><span style=3D"color:#000"><br><br>oms</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">std</span><span =
style=3D"color:#660">::</span><span style=3D"color:#000">move</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">a</span><span style=
=3D"color:#660">));</span><span style=3D"color:#000"><br></span></div></cod=
e></div>Will move <span style=3D"font-family:courier new,monospace">a</span=
> even if <span style=3D"font-family:courier new,monospace">a</span> is an =
lvalue reference, even if the object was still needed somewhere else (so to=
 be used with caution).<br></div></div></blockquote><div><br></div><div><br=
></div><div>And this is EXACTLY why move will not be deprecated - to force-=
cast a collapsing reference.=C2=A0</div><div><br></div><div><br></div><div>=
I am a bit confused.=C2=A0</div><div>I think you think about <font face=3D"=
courier new,monospace">auto&amp;&amp;</font> to be the type of <font face=
=3D"courier new,monospace">decltype(a), <font face=3D"arial,sans-serif">but=
 I think of it as collapsing reference because at it is at that point,=C2=
=A0</font></font></div><div><font face=3D"courier new,monospace"><font face=
=3D"arial,sans-serif">when it is still a collapsing reference, that the com=
piler will inject the correct impl of give. After collapse is way too late,=
 of course.=C2=A0</font></font></div></div></blockquote><div><br></div><div=
>I don&#39;t think about auto&amp;&amp; as decltype(a): it is not the same.=
 But this is irrelevant to my point.</div><div>You want to give a different=
 behavior to auto&amp;&amp; because it collapses references.</div></div></b=
lockquote><div><br></div><div><br></div><div><br>But it is different. It is=
 not a type declaration, its a language level template-expression declarati=
on, your collapser_t build-in if you will.</div><div>I have full right to t=
reat these as special, as the language already does.</div><div><br></div></=
div></blockquote><div><br></div><div>You have the right to treat these as s=
pecial. My question is (and was always): should you? Would it make sense? W=
ould it create some nasty problems we want to avoid?<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></di=
v><div><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>That&#39;s exactly the point I disagree.</div><div>C=
urrently, there is no way to tell when there is reference collapsing. And t=
hat&#39;s perfect because it is a tricky, yet useful, feature of C++.</div>=
</div></blockquote><div><br></div><div><br></div><div>After few template pr=
ocessing or argument passing it is lost, yes. </div><div>But at the top lev=
el is clear=C2=A0 - syntax of the form T&amp;&amp; will trigger reference c=
ollapsing (if any), and it is always correct to static_cast&lt;T&amp;&amp;&=
gt; to pass it on</div><div>In a way that case is the easiest, because the =
language is already smart about it.<br></div></div></blockquote><div><br></=
div><div>You just said it: at the top level. In most template metaprograms,=
 the top-level part is completely buried &quot;under&quot; several levels o=
f indirection.</div><div>And forwarding must work from the top level to the=
 deepest level and give the exact same result. Because it makes it easy to =
think about the code.</div><div>If &amp;&amp;&gt; works differently at the =
top level than at the other levels, then I have the feeling it will create =
more problems that solving.<br></div><div>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div><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>If y=
ou make something behaving differently when there is reference collapsing a=
nd where there isn&#39;t, the language will get more confusing.</div></div>=
</blockquote><div><br></div><div><br></div><div>As said, the language alrea=
dy does,=C2=A0 static_cast&lt;T&amp;&amp;&gt; no longer returns rvalue ref =
(as it &quot;obviously should&quot;) - it returns &amp;. yes this is confus=
ing, but that&#39;s how it is.<br></div><div><br></div></div></blockquote><=
div><br></div><div>Because static_cast doesn&#39;t care about reference col=
lapsing: it sees a type and use it. This type might have been collapsed, it=
 doesn&#39;t change the result.<br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>=C2=A0</div><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"><div><br></div><div>=
I would expect this:</div><div><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#008">using</span><span style=3D"color:#000"> A=
 </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </=
span><span style=3D"color:#008">int</span><span style=3D"color:#660">&amp;;=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">int=
</span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>A</span>=
<span style=3D"color:#660">&amp;&amp;</span><span style=3D"color:#000"> j <=
/span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> i</s=
pan><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">j</span>=
<span style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000=
"><br></span></div></code></div>to stay equivalent to this:</div><div><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">in=
t</span><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</spa=
n><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">&amp;</span><span style=3D"color:#000">j </span><sp=
an style=3D"color:#660">=3D</span><span style=3D"color:#000"> i</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">j</span><span sty=
le=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"><br></s=
pan></div></code></div></div><div><br></div><div>Because in both cases, j h=
ave the exact same type.</div><div>With what you propose, they will have di=
fferent behavior because of the way they are declared while being the same =
type.</div></div></blockquote><div><br></div><div><br></div><div><br>Today =
is not very different. If you forward&lt;int&gt;(j) - it is moved, if forwa=
rd&lt;A&gt;(j) - it will be forwarded.=C2=A0</div><div><br></div><div>And c=
omes the question. What is the intend of the user? Does he want to forward =
a &amp;? Why on earth he even THINKS he can do that?!?</div><div><br></div>=
<div>Wasn&#39;t he told in school &quot;you forward only forwarding referen=
ces&quot;? </div><div>In order to &quot;forward&quot; an &amp; - you MUST p=
ass through reference collapsing. These are the rules today! You must typed=
ef A&amp;&amp; or you must decltype(x) to get the exact type. </div></div><=
/blockquote><div><br></div><div>Those are not the today rules. If you want =
to forward a lvalue ref, just pass it. If you cannot know if it is a lvalue=
 or a rvalue ref, then you use <span style=3D"font-family: courier new, mon=
ospace;">std::forward</span>. If you want to forward a rvalue reference, yo=
u use <span style=3D"font-family: courier new, monospace;">std::move</span>=
..</div><div>These are the today rules.<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><div>So,=
 with an operator it is obvious what will be done in what case. If the user=
 &amp;&amp;&gt; a reference (he sees its an reference, in code), by todays =
rules, this MUST be a move, on another hand, is the type is hidden behind a=
 collapse (he sees its a T&amp;&amp;) - it MUST be forward. =C2=A0<br></div=
><div>(Needless to say, you never want to &quot;forward&quot; a &amp; - as =
you can just pass the variable as is.)</div><div><br></div><div><br>Sidenot=
e. Probably the example you are looking for:</div><div><br></div><div><font=
 face=3D"courier new,monospace">using A =3D C&amp;;<br>A j =3D c;<br>f(std:=
:forward&lt;A&gt;(j));</font></div><div><font face=3D"courier new,monospace=
"><br></font></div><div><font face=3D"courier new,monospace">using A =3D C&=
amp;;<br>A&amp;&amp; j =3D c;<br>f(std::forward&lt;A&gt;(j));</font></div><=
div><font face=3D"courier new,monospace"><br></font></div><div>Same today, =
different with &amp;&amp;&gt;.=C2=A0</div><div><br></div><div>But as said, =
it will still be correct (arguably more correct) , as the user is explicit =
what he declares and what he wants.<br></div></div></blockquote><div><br></=
div><div>That&#39;s actually what I want. Because in practice, there will b=
e many cases where A is not known by the user but just given by something e=
lse.</div><div>And if A and A&amp;&amp; are the same type, they should beha=
ve the same. But here it won&#39;t.<br></div><div>=C2=A0</div><blockquote c=
lass=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><br></div>=
<div><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"><di=
v dir=3D"ltr"><div>And what about:</div><div><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px"><code><div><span style=3D"color:#008">using</span><span style=3D"=
color:#000"> A </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">int</span><span style=3D"colo=
r:#660">&amp;;</span><span style=3D"color:#000"><br></span><span style=3D"c=
olor:#008">using</span><span style=3D"color:#000"> B </span><span style=3D"=
color:#660">=3D</span><span style=3D"color:#000"> A</span><span style=3D"co=
lor:#660">&amp;&amp;;</span><span style=3D"color:#000"><br><br></span><span=
 style=3D"color:#008">int</span><span style=3D"color:#000"> i </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>B j </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>foo</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><=
span style=3D"color:#000"> </span><span style=3D"color:#800">// shall it be=
 moved?</span><span style=3D"color:#000"><br></span></div></code></div><br>=
</div></div></blockquote><div><br></div><div>Of course not. B is reference =
collapsing &quot;expression&quot;/&quot;type&quot;, reference collapses are=
 AWAYS forwarded.=C2=A0 <br></div></div></blockquote><div><br></div><div>An=
d if B is not defined just above but given by a template parameter?</div><d=
iv><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-=
word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templ=
ate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> bar</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;=
&amp;);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">template<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
T t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">t</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&amp;&amp;&gt;);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">using</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
A </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&amp;;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">using</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> B </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;&amp;;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> j </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>A I </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>B J </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> j</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>foo</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">A</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt=
;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">I</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #800;" class=3D"styled-by-prettify">// call foo&lt;int&amp;&gt;() -&gt=
; bar&lt;int&amp;&amp;&gt;()</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>foo</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">B</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&gt;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">J</sp=
an><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: #800;" class=3D"styled-by-prettify">// call foo&lt;int&amp;&gt;() -=
&gt; bar&lt;int??&gt;()</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br>bar</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">I</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;&amp;&gt;);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// call=
 bar&lt;int&amp;&amp;&gt;()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>bar</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">J</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;&amp;&gt;);</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// call=
 bar&lt;int&amp;&gt;()</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span></div></code></div>Should the two calls to <span sty=
le=3D"font-family: courier new, monospace;">foo</span> behave the same, I b=
et so.</div><div>But <span style=3D"font-family: courier new, monospace;">B=
</span> was collapsed where <span style=3D"font-family: courier new, monosp=
ace;">A</span> was not.</div><div><br></div><div>And now, by introducing a =
wrapper, either the meaning of the code has changed (if <span style=3D"font=
-family: courier new, monospace;">foo&lt;B&gt;(J)</span> calls <span style=
=3D"font-family: courier new, monospace;">bar&lt;int&amp;&amp;&gt;()</span>=
) or you need to differentiate the 2 calls to foo disambiguation with somet=
hing that is not encoded in the type (and then generates 2 symbols).</div><=
div>None is satisfying to me.</div><div>What you probably want in the end i=
s: &quot;forwarding/universal&quot; references being part of the type syste=
m. Or similarly, encode in the type that references has been collapsed maki=
ng A and B from the example two distinct types with the exact same properti=
es.</div><div>The first might be feasible but would need big effort to stan=
dardize.</div><div>The second is completely out of question: <span style=3D=
"font-family: courier new, monospace;">A</span> and <span style=3D"font-fam=
ily: courier new, monospace;">B</span> would create different types when pa=
ssed in template parameters. (<span style=3D"font-family: courier new, mono=
space;">std::is_same&lt;A, B&gt;</span> would be false...)</div><div><br></=
div><div>Or maybe you&#39;re fine with wrapping some code can change the me=
aning of the code. But I&#39;m definitely not.<br></div><div><br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div></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><br></div><div>This would be completely new and unusual in t=
he language. This is what I want to avoid.</div><div>The type of the variab=
le alone should be enough to decide what to do. (the type of the expression=
 is obviously not enough).</div></div></blockquote><div><br></div><div><br>=
</div><div>As said, I am taping on the level before the type of the variabl=
e becomes finalized. When the auto&amp;&amp; is just an expression to captu=
re the type, whatever it is.</div><div><br></div><div>Only at this point, w=
e can have no-brain forward-or-move-you-know-best, because the compiler (pr=
eprocessor I guess, because there is no instantiations) has all the informa=
tion to do the right thing.=C2=A0</div><div><br></div><div>At type level th=
is can not be solved. <br></div><div><br></div></div></blockquote><div><br>=
</div><div>But the type system is the only part of the language you can rel=
iably use to build your operator if you want to avoid the problems I mentio=
ned earlier.</div><div>You&#39;re completely right saying the compiler has =
all the information to do the right thing, but only at the top level. But w=
e also want this to work with deeper levels. Because that&#39;s what is use=
d in template metapgrograms.<br></div><div>=C2=A0</div><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></div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>All my examples sh=
ow you what kind of code would behave differently.<br></div><div><br></div>=
<div>Just to clarify things a bit. If I insist, it is because I really want=
 to help you finding the problems with your approach (Whatever your approac=
h could be).</div><div>While I do prefer my solution, yours is also interes=
ting ;)<br></div></div></blockquote><div><br></div><div>I am very grateful =
to you, because with your use cases outside forwarding references (as per T=
he Standard) it helped me find the actual valid uses. After all both operat=
or()(A&amp;&amp;...) and auto&amp;&amp; var =3D =E2=80=A6 are not=C2=A0 for=
warding references (as per The Standard)=C2=A0</div></div></blockquote></di=
v>

<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/f955ea1c-7cbf-4077-96b4-fd00b110b0f3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f955ea1c-7cbf-4077-96b4-fd00b110b0f3=
%40isocpp.org</a>.<br />

------=_Part_4002_1936582330.1528707634763--

------=_Part_4001_251565175.1528707634762--

.


Author: mihailnajdenov@gmail.com
Date: Mon, 11 Jun 2018 06:37:18 -0700 (PDT)
Raw View
------=_Part_100521_1463150756.1528724238293
Content-Type: multipart/alternative;
 boundary="----=_Part_100522_710745864.1528724238294"

------=_Part_100522_710745864.1528724238294
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable



On Monday, June 11, 2018 at 12:00:34 PM UTC+3, floria...@gmail.com wrote:
>
>
>
> Le lundi 11 juin 2018 10:17:20 UTC+2, mihailn...@gmail.com a =C3=A9crit :
>>
>>
>>
>> On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, floria...@gmail.com wrote=
:
>>>
>>>
>>>
>>> Le dimanche 10 juin 2018 20:59:45 UTC+2, mihailn...@gmail.com a =C3=A9c=
rit :
>>>>
>>>>
>>>>
>>>> On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, floria...@gmail.com=20
>>>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> Le dimanche 10 juin 2018 18:30:45 UTC+2, mihailn...@gmail.com a=20
>>>>> =C3=A9crit :
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, floria...@gmail.com=20
>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Le dimanche 10 juin 2018 16:33:59 UTC+2, mihailn...@gmail.com a=20
>>>>>>> =C3=A9crit :
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, floria...@gmail.com=
=20
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Le dimanche 10 juin 2018 14:23:38 UTC+2, mihailn...@gmail.com a=
=20
>>>>>>>>> =C3=A9crit :...
>>>>>>>>>
>>>>>>>> ..
>>>>>>>
>>>>>> =20
>
>>
>> =20
>>
>>> I don't want such a collapse_t to be in the standard at all. But it is=
=20
>>> possible to write it and use it.
>>> And to some extent (not this particular example), it is used.
>>> =20
>>>
>>>> ...
>>>>
>>>
>>
>> But it is different. It is not a type declaration, its a language level=
=20
>> template-expression declaration, your collapser_t build-in if you will.
>> I have full right to treat these as special, as the language already doe=
s.
>>
>>
> You have the right to treat these as special. My question is (and was=20
> always): should you? Would it make sense? Would it create some nasty=20
> problems we want to avoid?
>

As I don't invent new rules or new types I doubt there will be problems,=20
but of course all cases should be reviewed. After all you already found one=
=20
case when it will do the wrong thing - the operator() case.
But after that, with the new rules, I fail to find a problem, granted the=
=20
system is not as powerful as you might want, but as I said - I don't invent=
=20
new rules.=20
=20

> =20
>
>>
>> =20
>>
>>> That's exactly the point I disagree.
>>> Currently, there is no way to tell when there is reference collapsing.=
=20
>>> And that's perfect because it is a tricky, yet useful, feature of C++.
>>>
>>
>>
>> After few template processing or argument passing it is lost, yes.=20
>> But at the top level is clear  - syntax of the form T&& will trigger=20
>> reference collapsing (if any), and it is always correct to static_cast<T=
&&>=20
>> to pass it on
>> In a way that case is the easiest, because the language is already smart=
=20
>> about it.
>>
>
> You just said it: at the top level. In most template metaprograms, the=20
> top-level part is completely buried "under" several levels of indirection=
..
> And forwarding must work from the top level to the deepest level and give=
=20
> the exact same result. Because it makes it easy to think about the code.
>


Yeah, but it does not right now. Forwarding is one level (at best), after=
=20
that it must be reinitiated.=20

You clearly want forwarding type/reference and you might be right, but ...

=20

> If &&> works differently at the top level than at the other levels, then =
I=20
> have the feeling it will create more problems that solving.
> =20
>
>>
>> =20
>>
>>> If you make something behaving differently when there is reference=20
>>> collapsing and where there isn't, the language will get more confusing.
>>>
>>
>>
>> As said, the language already does,  static_cast<T&&> no longer returns=
=20
>> rvalue ref (as it "obviously should") - it returns &. yes this is=20
>> confusing, but that's how it is.
>>
>>
> Because static_cast doesn't care about reference collapsing: it sees a=20
> type and use it. This type might have been collapsed, it doesn't change t=
he=20
> result.
>

What I meant was, it in general produces what it is in the <>, but with=20
collapsing it says one thing in the <>, but produces anther - the result of=
=20
collapse. =20
=20

> =20
>
>> =20
>>
>>>
>>> I would expect this:
>>> using A =3D int&;
>>> int i =3D 0;
>>> A&& j =3D i;
>>> foo(j&&>);
>>> to stay equivalent to this:
>>> int i =3D 0;
>>> int &j =3D i;
>>> foo(j&&>);
>>>
>>> Because in both cases, j have the exact same type.
>>> With what you propose, they will have different behavior because of the=
=20
>>> way they are declared while being the same type.
>>>
>>
>>
>>
>> Today is not very different. If you forward<int>(j) - it is moved, if=20
>> forward<A>(j) - it will be forwarded.=20
>>
>> And comes the question. What is the intend of the user? Does he want to=
=20
>> forward a &? Why on earth he even THINKS he can do that?!?
>>
>> Wasn't he told in school "you forward only forwarding references"?=20
>> In order to "forward" an & - you MUST pass through reference collapsing.=
=20
>> These are the rules today! You must typedef A&& or you must decltype(x) =
to=20
>> get the exact type.=20
>>
>
> Those are not the today rules. If you want to forward a lvalue ref, just=
=20
> pass it. If you cannot know if it is a lvalue or a rvalue ref, then you u=
se=20
> std::forward. If you want to forward a rvalue reference, you use std::mov=
e
> .
>


I mean if really, really, really wants to forward it like the big boys do,=
=20
for no good reason.=20

=20

> These are the today rules.
> =20
>
>>
>> So, with an operator it is obvious what will be done in what case. If th=
e=20
>> user &&> a reference (he sees its an reference, in code), by todays rule=
s,=20
>> this MUST be a move, on another hand, is the type is hidden behind a=20
>> collapse (he sees its a T&&) - it MUST be forward. =20
>> (Needless to say, you never want to "forward" a & - as you can just pass=
=20
>> the variable as is.)
>>
>>
>> Sidenote. Probably the example you are looking for:
>>
>> using A =3D C&;
>> A j =3D c;
>> f(std::forward<A>(j));
>>
>> using A =3D C&;
>> A&& j =3D c;
>> f(std::forward<A>(j));
>>
>> Same today, different with &&>.=20
>>
>> But as said, it will still be correct (arguably more correct) , as the=
=20
>> user is explicit what he declares and what he wants.
>>
>
> That's actually what I want. Because in practice, there will be many case=
s=20
> where A is not known by the user but just given by something else.
> And if A and A&& are the same type, they should behave the same. But here=
=20
> it won't.
> =20
>
>>
>>
>> =20
>>
>>> And what about:
>>> using A =3D int&;
>>> using B =3D A&&;
>>>
>>> int i =3D 0;
>>> B j =3D i;
>>> foo(j&&>); // shall it be moved?
>>>
>>>
>> Of course not. B is reference collapsing "expression"/"type", reference=
=20
>> collapses are AWAYS forwarded. =20
>>
>
> And if B is not defined just above but given by a template parameter?
> template <class T> void bar(T&&);
> template <class T> void foo(T t) { bar(t&&>); }
>
> using A =3D int&;
> using B =3D int&&;
>
> int i =3D 0, j =3D 0;
> A I =3D i;
> B J =3D j;
> foo<A>(I); // call foo<int&>() -> bar<int&&>()
> foo<B>(J); // call foo<int&>() -> bar<int??>()
>
> bar(I&&>); // call bar<int&&>()
> bar(J&&>); // call bar<int&>()
> Should the two calls to foo behave the same, I bet so.
> But B was collapsed where A was not.
>


This code does not compile today. In any case there is no collapsing on the=
=20
call site of nether foo nor bar.=20

Here the code that compiles

class C {};=20

template <class T> void bar(T&&);
template <class T> void foo(T t) { bar(t&&>); }

// main

using A =3D C&;
using B =3D C&&;

C i;
A I =3D i;
B J =3D C();
foo<A>(I); // call foo<C&>()
foo<B>(J&&>); // call foo<C&&>()=20

bar(I&&>); // call bar<C&&>()
bar(J&&>); // call bar<C&&>()

As you can see bar are the same as there is no collapsing and we have two=
=20
moves.=20

foo-s are different because again no collapsing, just type alias as=20
explicit argument



> And now, by introducing a wrapper, either the meaning of the code has=20
> changed (if foo<B>(J) calls bar<int&&>()) or you need to differentiate=20
> the 2 calls to foo disambiguation with something that is not encoded in t=
he=20
> type (and then generates 2 symbols).
> None is satisfying to me.
> What you probably want in the end is: "forwarding/universal" references=
=20
> being part of the type system. Or similarly, encode in the type that=20
> references has been collapsed making A and B from the example two distinc=
t=20
> types with the exact same properties.
> The first might be feasible but would need big effort to standardize.
> The second is completely out of question: A and B would create different=
=20
> types when passed in template parameters. (std::is_same<A, B> would be=20
> false...)
>
> Or maybe you're fine with wrapping some code can change the meaning of th=
e=20
> code. But I'm definitely not.
>
> =20
>
>> =20
>>
>>>
>>> This would be completely new and unusual in the language. This is what =
I=20
>>> want to avoid.
>>> The type of the variable alone should be enough to decide what to do.=
=20
>>> (the type of the expression is obviously not enough).
>>>
>>
>>
>> As said, I am taping on the level before the type of the variable become=
s=20
>> finalized. When the auto&& is just an expression to capture the type,=20
>> whatever it is.
>>
>> Only at this point, we can have no-brain forward-or-move-you-know-best,=
=20
>> because the compiler (preprocessor I guess, because there is no=20
>> instantiations) has all the information to do the right thing.=20
>>
>> At type level this can not be solved.=20
>>
>>
> But the type system is the only part of the language you can reliably use=
=20
> to build your operator if you want to avoid the problems I mentioned=20
> earlier.
> You're completely right saying the compiler has all the information to do=
=20
> the right thing, but only at the top level. But we also want this to work=
=20
> with deeper levels. Because that's what is used in template metapgrograms=
..
>


This would be a different proposal, you probably agree. And I will be happy=
=20
to see ideas or simply requirements.=20
=20

> =20
>
>> =20
>>
>>> All my examples show you what kind of code would behave differently.
>>>
>>> Just to clarify things a bit. If I insist, it is because I really want=
=20
>>> to help you finding the problems with your approach (Whatever your appr=
oach=20
>>> could be).
>>> While I do prefer my solution, yours is also interesting ;)
>>>
>>
>> I am very grateful to you, because with your use cases outside forwardin=
g=20
>> references (as per The Standard) it helped me find the actual valid uses=
..=20
>> After all both operator()(A&&...) and auto&& var =3D =E2=80=A6 are not  =
forwarding=20
>> references (as per The Standard)=20
>>
>

--=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/94a919fe-cae3-42bb-a959-be26e9c2466a%40isocpp.or=
g.

------=_Part_100522_710745864.1528724238294
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, June 11, 2018 at 12:00:34 PM UTC+3, flo=
ria...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><br><br>Le lundi 11 juin 2018 10:17:20 UTC+2, <a>mihailn...@gmail=
..com</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 10:25:01 PM UTC+3, <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"><br><br>Le dimanche 10 juin 2018 20:59:45 UTC+2, <a>mihailn...@gmail.c=
om</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 8:17:14 PM UTC+3, <a>floria...=
@gmail.com</a> wrote:<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"><br><br>Le dimanche 10 juin 2018 18:30:45 UTC+2, <a>mihailn...@gmail.com=
</a> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 6:09:36 PM UTC+3, <a>floria...@gm=
ail.com</a> wrote:<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">=
<br><br>Le dimanche 10 juin 2018 16:33:59 UTC+2, <a>mihailn...@gmail.com</a=
> a =C3=A9crit=C2=A0:<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"><br><br>On Sunday, June 10, 2018 at 3:56:26 PM UTC+3, <a>floria...@gmail=
..com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br=
><br>Le dimanche 10 juin 2018 14:23:38 UTC+2, <a>mihailn...@gmail.com</a> a=
 =C3=A9crit=C2=A0:...</div></blockquote></div></blockquote><div>..</div></d=
iv></blockquote></div></blockquote></div></blockquote></div></blockquote></=
div></blockquote></div></blockquote><div>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div><br></div><div>=C2=A0</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>I don&#39;t want such=
 a collapse_t to be in the standard at all. But it is possible to write it =
and use it.</div><div>And to some extent (not this particular example), it =
is used.<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>...</div></div></blockquote></div></blockquote><div>=
<br></div><div><br>But it is different. It is not a type declaration, its a=
 language level template-expression declaration, your collapser_t build-in =
if you will.</div><div>I have full right to treat these as special, as the =
language already does.</div><div><br></div></div></blockquote><div><br></di=
v><div>You have the right to treat these as special. My question is (and wa=
s always): should you? Would it make sense? Would it create some nasty prob=
lems we want to avoid?<br></div></div></blockquote><div><br></div><div>As I=
 don&#39;t invent new rules or new types I doubt there will be problems, bu=
t of course all cases should be reviewed. After all you already found one c=
ase when it will do the wrong thing - the operator() case.</div><div>But af=
ter that, with the new rules, I fail to find a problem, granted the system =
is not as powerful as you might want, but as I said - I don&#39;t invent ne=
w rules.=C2=A0</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></div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div></div><div><br></div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>That&#39;s =
exactly the point I disagree.</div><div>Currently, there is no way to tell =
when there is reference collapsing. And that&#39;s perfect because it is a =
tricky, yet useful, feature of C++.</div></div></blockquote><div><br></div>=
<div><br></div><div>After few template processing or argument passing it is=
 lost, yes. </div><div>But at the top level is clear=C2=A0 - syntax of the =
form T&amp;&amp; will trigger reference collapsing (if any), and it is alwa=
ys correct to static_cast&lt;T&amp;&amp;&gt; to pass it on</div><div>In a w=
ay that case is the easiest, because the language is already smart about it=
..<br></div></div></blockquote><div><br></div><div>You just said it: at the =
top level. In most template metaprograms, the top-level part is completely =
buried &quot;under&quot; several levels of indirection.</div><div>And forwa=
rding must work from the top level to the deepest level and give the exact =
same result. Because it makes it easy to think about the code.</div></div><=
/blockquote><div><br></div><div><br></div><div>Yeah, but it does not right =
now. Forwarding is one level (at best), after that it must be reinitiated.=
=C2=A0</div><div><br></div><div>You clearly want forwarding type/reference =
and you might be right, but ...</div><div><br></div><div>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>If &amp;&amp;&=
gt; works differently at the top level than at the other levels, then I hav=
e the feeling it will create more problems that solving.<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></di=
v><div><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>If you make something behaving differently when ther=
e is reference collapsing and where there isn&#39;t, the language will get =
more confusing.</div></div></blockquote><div><br></div><div><br></div><div>=
As said, the language already does,=C2=A0 static_cast&lt;T&amp;&amp;&gt; no=
 longer returns rvalue ref (as it &quot;obviously should&quot;) - it return=
s &amp;. yes this is confusing, but that&#39;s how it is.<br></div><div><br=
></div></div></blockquote><div><br></div><div>Because static_cast doesn&#39=
;t care about reference collapsing: it sees a type and use it. This type mi=
ght have been collapsed, it doesn&#39;t change the result.<br></div></div><=
/blockquote><div><br></div><div>What I meant was, it in general produces wh=
at it is in the &lt;&gt;, but with collapsing it says one thing in the &lt;=
&gt;, but produces anther - the result of collapse. =C2=A0</div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></=
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></div><div>=C2=A0</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><br></div><div>I would expect this:</div><div><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">using</=
span><span style=3D"color:#000"> A </span><span style=3D"color:#660">=3D</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#008">int</span=
><span style=3D"color:#660">&amp;;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#000"> i </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#066">0</span><span style=3D"color:#660">;</span><span=
 style=3D"color:#000"><br>A</span><span style=3D"color:#660">&amp;&amp;</sp=
an><span style=3D"color:#000"> j </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> i</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"><br>foo</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt;=
);</span><span style=3D"color:#000"><br></span></div></code></div>to stay e=
quivalent to this:</div><div><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">int</span><span style=3D"color:#000"> i </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span=
><span style=3D"color:#066">0</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><span=
 style=3D"color:#000">j </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>foo</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">j</span><span style=3D"color:#660">&amp;&amp;&gt;);</span>=
<span style=3D"color:#000"><br></span></div></code></div></div><div><br></d=
iv><div>Because in both cases, j have the exact same type.</div><div>With w=
hat you propose, they will have different behavior because of the way they =
are declared while being the same type.</div></div></blockquote><div><br></=
div><div><br></div><div><br>Today is not very different. If you forward&lt;=
int&gt;(j) - it is moved, if forward&lt;A&gt;(j) - it will be forwarded.=C2=
=A0</div><div><br></div><div>And comes the question. What is the intend of =
the user? Does he want to forward a &amp;? Why on earth he even THINKS he c=
an do that?!?</div><div><br></div><div>Wasn&#39;t he told in school &quot;y=
ou forward only forwarding references&quot;? </div><div>In order to &quot;f=
orward&quot; an &amp; - you MUST pass through reference collapsing. These a=
re the rules today! You must typedef A&amp;&amp; or you must decltype(x) to=
 get the exact type. </div></div></blockquote><div><br></div><div>Those are=
 not the today rules. If you want to forward a lvalue ref, just pass it. If=
 you cannot know if it is a lvalue or a rvalue ref, then you use <span styl=
e=3D"font-family:courier new,monospace">std::forward</span>. If you want to=
 forward a rvalue reference, you use <span style=3D"font-family:courier new=
,monospace">std::move</span>.</div></div></blockquote><div><br></div><div><=
br></div><div>I mean if really, really, really wants to forward it like the=
 big boys do, for no good reason.=C2=A0</div><div><br></div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>These =
are the today rules.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div><br></div><div>So, with an operator it is=
 obvious what will be done in what case. If the user &amp;&amp;&gt; a refer=
ence (he sees its an reference, in code), by todays rules, this MUST be a m=
ove, on another hand, is the type is hidden behind a collapse (he sees its =
a T&amp;&amp;) - it MUST be forward. =C2=A0<br></div><div>(Needless to say,=
 you never want to &quot;forward&quot; a &amp; - as you can just pass the v=
ariable as is.)</div><div><br></div><div><br>Sidenote. Probably the example=
 you are looking for:</div><div><br></div><div><font face=3D"courier new,mo=
nospace">using A =3D C&amp;;<br>A j =3D c;<br>f(std::forward&lt;A&gt;(j));<=
/font></div><div><font face=3D"courier new,monospace"><br></font></div><div=
><font face=3D"courier new,monospace">using A =3D C&amp;;<br>A&amp;&amp; j =
=3D c;<br>f(std::forward&lt;A&gt;(j));</font></div><div><font face=3D"couri=
er new,monospace"><br></font></div><div>Same today, different with &amp;&am=
p;&gt;.=C2=A0</div><div><br></div><div>But as said, it will still be correc=
t (arguably more correct) , as the user is explicit what he declares and wh=
at he wants.<br></div></div></blockquote><div><br></div><div>That&#39;s act=
ually what I want. Because in practice, there will be many cases where A is=
 not known by the user but just given by something else.</div><div>And if A=
 and A&amp;&amp; are the same type, they should behave the same. But here i=
t won&#39;t.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div></div><div><br></div><div><br></div><div>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>And what =
about:</div><div><div style=3D"background-color:rgb(250,250,250);border-col=
or:rgb(187,187,187);border-style:solid;border-width:1px"><code><div><span s=
tyle=3D"color:#008">using</span><span style=3D"color:#000"> A </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">int</span><span style=3D"color:#660">&amp;;</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#008">using</span><span=
 style=3D"color:#000"> B </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> A</span><span style=3D"color:#660">&amp;&amp;;</span>=
<span style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span><s=
pan style=3D"color:#660">;</span><span style=3D"color:#000"><br>B j </span>=
<span style=3D"color:#660">=3D</span><span style=3D"color:#000"> i</span><s=
pan style=3D"color:#660">;</span><span style=3D"color:#000"><br>foo</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">j</span><span =
style=3D"color:#660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#800">// shall it be moved?</span><span style=3D"c=
olor:#000"><br></span></div></code></div><br></div></div></blockquote><div>=
<br></div><div>Of course not. B is reference collapsing &quot;expression&qu=
ot;/&quot;type&quot;, reference collapses are AWAYS forwarded.=C2=A0 <br></=
div></div></blockquote><div><br></div><div>And if B is not defined just abo=
ve but given by a template parameter?</div><div><div style=3D"background-co=
lor:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;borde=
r-width:1px"><code><div><span style=3D"color:#008">template</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> T</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">void</span><span style=3D"color:#000"> bar</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">T</span><span style=3D"=
color:#660">&amp;&amp;);</span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">template</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">&lt;</span><span style=3D"color:#008">class</span><s=
pan style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">void</span><span=
 style=3D"color:#000"> foo</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">T t</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"=
color:#000"> bar</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">t</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#008">using</span><span=
 style=3D"color:#000"> A </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#660">&amp;;</span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">using</span><span style=3D"color:#000"> B </span><span=
 style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">int</span><span style=3D"color:#660">&amp;&amp;;</span><=
span style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> i </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#066">0</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> j </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>A I </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>B J </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000"> j</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"><br>foo</span><span style=3D"color:#660">&lt;</span><span styl=
e=3D"color:#000">A</span><span style=3D"color:#660">&gt;(</span><span style=
=3D"color:#000">I</span><span style=3D"color:#660">);</span><span style=3D"=
color:#000"> </span><span style=3D"color:#800">// call foo&lt;int&amp;&gt;(=
) -&gt; bar&lt;int&amp;&amp;&gt;()</span><span style=3D"color:#000"><br>foo=
</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#000">B</=
span><span style=3D"color:#660">&gt;(</span><span style=3D"color:#000">J</s=
pan><span style=3D"color:#660">);</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#800">// call foo&lt;int&amp;&gt;() -&gt; bar&lt;int??=
&gt;()</span><span style=3D"color:#000"><br><br>bar</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">I</span><span style=3D"color:#=
660">&amp;&amp;&gt;);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">// call bar&lt;int&amp;&amp;&gt;()</span><span style=3D"col=
or:#000"><br>bar</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">J</span><span style=3D"color:#660">&amp;&amp;&gt;);</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#800">// call bar&lt;int&a=
mp;&gt;()</span><span style=3D"color:#000"><br></span></div></code></div>Sh=
ould the two calls to <span style=3D"font-family:courier new,monospace">foo=
</span> behave the same, I bet so.</div><div>But <span style=3D"font-family=
:courier new,monospace">B</span> was collapsed where <span style=3D"font-fa=
mily:courier new,monospace">A</span> was not.</div></div></blockquote><div>=
<br></div><div><br></div><div>This code does not compile today. In any case=
 there is no collapsing on the call site of nether foo nor bar.=C2=A0</div>=
<div><br></div><div>Here the code that compiles<br></div><font face=3D"cour=
ier new,monospace"><br>class C {};=C2=A0<br><br>template &lt;class T&gt; vo=
id bar(T&amp;&amp;);<br>template &lt;class T&gt; void foo(T t) { bar(t&amp;=
&amp;&gt;); }<br><div><br></div><div>// main</div><div><br></div>using A =
=3D C&amp;;<br>using B =3D C&amp;&amp;;<br><br>C i;<br>A I =3D i;<br>B J =
=3D C();<br>foo&lt;A&gt;(I); // call foo&lt;C&amp;&gt;()<br>foo&lt;B&gt;(J&=
amp;&amp;&gt;); // call foo&lt;C&amp;&amp;&gt;()=C2=A0<br><br>bar(I&amp;&am=
p;&gt;); // call bar&lt;C&amp;&amp;&gt;()<br>bar(J&amp;&amp;&gt;); // call =
bar&lt;C&amp;&amp;&gt;()</font><br><br><div>As you can see bar are the same=
 as there is no collapsing and we have two moves.=C2=A0</div><div><br></div=
><div>foo-s are different because again no collapsing, just type alias as e=
xplicit argument</div><div><br></div><br> <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><div>And now, by introducing a =
wrapper, either the meaning of the code has changed (if <span style=3D"font=
-family:courier new,monospace">foo&lt;B&gt;(J)</span> calls <span style=3D"=
font-family:courier new,monospace">bar&lt;int&amp;&amp;&gt;()</span>) or yo=
u need to differentiate the 2 calls to foo disambiguation with something th=
at is not encoded in the type (and then generates 2 symbols).</div><div>Non=
e is satisfying to me.</div><div>What you probably want in the end is: &quo=
t;forwarding/universal&quot; references being part of the type system. Or s=
imilarly, encode in the type that references has been collapsed making A an=
d B from the example two distinct types with the exact same properties.</di=
v><div>The first might be feasible but would need big effort to standardize=
..</div><div>The second is completely out of question: <span style=3D"font-f=
amily:courier new,monospace">A</span> and <span style=3D"font-family:courie=
r new,monospace">B</span> would create different types when passed in templ=
ate parameters. (<span style=3D"font-family:courier new,monospace">std::is_=
same&lt;A, B&gt;</span> would be false...)</div><div><br></div><div>Or mayb=
e you&#39;re fine with wrapping some code can change the meaning of the cod=
e. But I&#39;m definitely not.<br></div><div><br></div><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></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><div>This would be completely new and unusual in the language. This i=
s what I want to avoid.</div><div>The type of the variable alone should be =
enough to decide what to do. (the type of the expression is obviously not e=
nough).</div></div></blockquote><div><br></div><div><br></div><div>As said,=
 I am taping on the level before the type of the variable becomes finalized=
.. When the auto&amp;&amp; is just an expression to capture the type, whatev=
er it is.</div><div><br></div><div>Only at this point, we can have no-brain=
 forward-or-move-you-know-best, because the compiler (preprocessor I guess,=
 because there is no instantiations) has all the information to do the righ=
t thing.=C2=A0</div><div><br></div><div>At type level this can not be solve=
d. <br></div><div><br></div></div></blockquote><div><br></div><div>But the =
type system is the only part of the language you can reliably use to build =
your operator if you want to avoid the problems I mentioned earlier.</div><=
div>You&#39;re completely right saying the compiler has all the information=
 to do the right thing, but only at the top level. But we also want this to=
 work with deeper levels. Because that&#39;s what is used in template metap=
grograms.<br></div></div></blockquote><div><br></div><div><br></div><div>Th=
is would be a different proposal, you probably agree. And I will be happy t=
o see ideas or simply requirements.=C2=A0</div><div>=C2=A0</div><blockquote=
 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><div>=C2=A0</=
div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><di=
v>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
>All my examples show you what kind of code would behave differently.<br></=
div><div><br></div><div>Just to clarify things a bit. If I insist, it is be=
cause I really want to help you finding the problems with your approach (Wh=
atever your approach could be).</div><div>While I do prefer my solution, yo=
urs is also interesting ;)<br></div></div></blockquote><div><br></div><div>=
I am very grateful to you, because with your use cases outside forwarding r=
eferences (as per The Standard) it helped me find the actual valid uses. Af=
ter all both operator()(A&amp;&amp;...) and auto&amp;&amp; var =3D =E2=80=
=A6 are not=C2=A0 forwarding references (as per The Standard)=C2=A0</div></=
div></blockquote></div></blockquote></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/94a919fe-cae3-42bb-a959-be26e9c2466a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/94a919fe-cae3-42bb-a959-be26e9c2466a=
%40isocpp.org</a>.<br />

------=_Part_100522_710745864.1528724238294--

------=_Part_100521_1463150756.1528724238293--

.


Author: Barry Revzin <barry.revzin@gmail.com>
Date: Mon, 11 Jun 2018 08:30:04 -0700 (PDT)
Raw View
------=_Part_101477_522928968.1528731005044
Content-Type: multipart/alternative;
 boundary="----=_Part_101478_950551844.1528731005044"

------=_Part_101478_950551844.1528731005044
Content-Type: text/plain; charset="UTF-8"



On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, mihailn...@gmail.com wrote:
>
> This is continuation of a previous topic
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
>
> Hello, I have written a proposal for merging `forward` and `move` behind a
> new postscript operator &&>
>
> This is the initial draft. Feedback is welcome.
>
> Thank You
> MihailNaydenov
>


As I mentioned in the previous thread, p0644 was discussed and ultimately
rejected in Albuquerque. I have no reason to believe that it was rejected
because the operator I proposed was *prefix* rather than *postfix*. All of
the concerns would apply just the same. For instance, from the motivating
example, this:

func&&>(args&&>...);

has *wildly different *meaning than this:

func&&(args&&...);

despite looking almost exactly the same. Moreover, this paper introduces a
novel glyph (&&>) which should in of itself have a reasonably high bar for
adoption and I doubt that this kind of abbreviating syntax would gain
consensus for the new token.

Separately, I don't think replacing move() with a glyph is particularly
motivating. move() is quite a bit shorter than forward() because you don't
need the extra type, and is pretty clear annotation for what the code is
doing.

--
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/c5ba7841-4128-4637-aee0-1676187881a7%40isocpp.org.

------=_Part_101478_950551844.1528731005044
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, mih=
ailn...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div>This is continuation of a <a href=3D"https://groups.google.=
com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" target=3D"_b=
lank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.googl=
e.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return=
 true;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/=
d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;">previous to=
pic</a>=C2=A0</div><div><br></div><div>Hello, I have written a proposal for=
 merging `forward` and `move` behind a new postscript operator &amp;&amp;&g=
t;</div><div><br></div><div>This is the initial draft. Feedback is welcome.=
</div><div><br></div><div>Thank You<br></div><div>MihailNaydenov=C2=A0</div=
></div></blockquote><div><br></div><div><br></div><div>As I mentioned in th=
e previous thread, p0644 was discussed and ultimately rejected in Albuquerq=
ue. I have no reason to believe that it was rejected because the operator I=
 proposed was <i>prefix</i>=C2=A0rather than <i>postfix</i>. All of the con=
cerns would apply just the same. For instance, from the motivating example,=
 this:</div><div><br></div><div><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><font color=3D"#660066"><span style=3D=
"color: #000;" class=3D"styled-by-prettify">func</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&amp;&amp;&gt;(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">args</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&amp;&amp;&gt;...);</span></font></div=
></code></div><br>has <i>wildly different </i>meaning than this:</div><div>=
<br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><font color=3D"#660066"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">func</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&amp;&amp;(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">args</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&amp;&amp;...);</span></font></div></code></div><br>despi=
te looking almost exactly the same. Moreover, this paper introduces a novel=
 glyph (&amp;&amp;&gt;) which should in of itself have a reasonably high ba=
r for adoption and I doubt that this kind of abbreviating syntax would gain=
 consensus for the new token.=C2=A0</div><div><br></div><div>Separately, I =
don&#39;t think replacing move() with a glyph is particularly motivating. m=
ove() is quite a bit shorter than forward() because you don&#39;t need the =
extra type, and is pretty clear annotation for what the code is doing.<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/c5ba7841-4128-4637-aee0-1676187881a7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c5ba7841-4128-4637-aee0-1676187881a7=
%40isocpp.org</a>.<br />

------=_Part_101478_950551844.1528731005044--

------=_Part_101477_522928968.1528731005044--

.


Author: mihailnajdenov@gmail.com
Date: Tue, 12 Jun 2018 01:35:33 -0700 (PDT)
Raw View
------=_Part_112323_446883098.1528792533526
Content-Type: multipart/alternative;
 boundary="----=_Part_112324_1779233920.1528792533527"

------=_Part_112324_1779233920.1528792533527
Content-Type: text/plain; charset="UTF-8"



On Monday, June 11, 2018 at 6:30:05 PM UTC+3, Barry Revzin wrote:
>
>
>
> On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, mihailn...@gmail.com wrote:
>>
>> This is continuation of a previous topic
>> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>>
>>
>> Hello, I have written a proposal for merging `forward` and `move` behind
>> a new postscript operator &&>
>>
>> This is the initial draft. Feedback is welcome.
>>
>> Thank You
>> MihailNaydenov
>>
>
>
> As I mentioned in the previous thread, p0644 was discussed and ultimately
> rejected in Albuquerque. I have no reason to believe that it was rejected
> because the operator I proposed was *prefix* rather than *postfix*. All
> of the concerns would apply just the same. For instance, from the
> motivating example, this:
>
> func&&>(args&&>...);
>
> has *wildly different *meaning than this:
>
> func&&(args&&...);
>
>

Yeah, but this is already true for * and & as well. The are not "almost the
same", but exactly the same and used with wildly different meanings
depending on the context.

a = b*c;
a = b(*c);

a = b&c;
a = &c;

etc.



> despite looking almost exactly the same. Moreover, this paper introduces a
> novel glyph (&&>) which should in of itself have a reasonably high bar for
> adoption and I doubt that this kind of abbreviating syntax would gain
> consensus for the new token.
>


Fair enough - that is the best I got. Alternatively a keyword might be
used, but that's not that easy either. Suggestions are always welcome



>
> Separately, I don't think replacing move() with a glyph is particularly
> motivating. move() is quite a bit shorter than forward() because you don't
> need the extra type, and is pretty clear annotation for what the code is
> doing.
>


I don't believe it's that simple. It is not about just verbosity. Even if
put the issue of two separate functions aside, the use of a function itself
is a crutch.

This is because the core language feature now depends on the standard
library. Think about it -* you cant use the language if you don't either
use the 'std' *(library) helper functions or be "a pro" and use static_cast.
This is stating to look like C where you can't create objects without using
the library.

These things are not pretty to users new to c++.
They might get used to the funny type decoration (&&) but the use of some
special function to use them will not feel right. Things are even worse
when are introduced to forward, where "the same" (in their eyes!) type,
decorated with &&, must be used with yet another function.


Imagine - no operator*, but a library std::deref. We are at the same place
with rvalue references (be it in "forwarding from" or standard).


My point is this - language level features must use language level tools.
Otherwise something went wrong in the design and we need to use a crutch.
My second point is the use of move and forward as separate functions is
redundant in de facto all cases.

So the number of tokens is not the primary concern.


--
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/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%40isocpp.org.

------=_Part_112324_1779233920.1528792533527
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Monday, June 11, 2018 at 6:30:05 PM UTC+3, Barr=
y Revzin 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=
"><br><br>On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, <a>mihailn...@gmai=
l.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"><d=
iv>This is continuation of a <a onmousedown=3D"this.href=3D&#39;https://gro=
ups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#3=
9;;return true;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/is=
ocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;" hr=
ef=3D"https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7b=
o/wXHhTLpbDQAJ" target=3D"_blank" rel=3D"nofollow">previous topic</a>=C2=A0=
</div><div><br></div><div>Hello, I have written a proposal for merging `for=
ward` and `move` behind a new postscript operator &amp;&amp;&gt;</div><div>=
<br></div><div>This is the initial draft. Feedback is welcome.</div><div><b=
r></div><div>Thank You<br></div><div>MihailNaydenov=C2=A0</div></div></bloc=
kquote><div><br></div><div><br></div><div>As I mentioned in the previous th=
read, p0644 was discussed and ultimately rejected in Albuquerque. I have no=
 reason to believe that it was rejected because the operator I proposed was=
 <i>prefix</i>=C2=A0rather than <i>postfix</i>. All of the concerns would a=
pply just the same. For instance, from the motivating example, this:</div><=
div><br></div><div><div style=3D"background-color:rgb(250,250,250);border-c=
olor:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-w=
ord"><code><div><font color=3D"#660066"><span style=3D"color:#000">func</sp=
an><span style=3D"color:#660">&amp;&amp;&gt;(</span><span style=3D"color:#0=
00">args</span><span style=3D"color:#660">&amp;&amp;&gt;...);</span></font>=
</div></code></div><br>has <i>wildly different </i>meaning than this:</div>=
<div><br></div><div><div 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><div><font color=3D"#660066"><span style=3D"color:#000">func</s=
pan><span style=3D"color:#660">&amp;&amp;(</span><span style=3D"color:#000"=
>args</span><span style=3D"color:#660">&amp;&amp;...);</span></font></div><=
/code></div><br></div></div></blockquote><div><br></div><div><br></div><div=
>Yeah, but this is already true for * and &amp; as well. The are not &quot;=
almost the same&quot;, but exactly the same and used with wildly different =
meanings depending on the context. =C2=A0=C2=A0</div><div><br></div><div><f=
ont face=3D"courier new,monospace">a =3D b*c;</font></div><div><font face=
=3D"courier new,monospace"><span style=3D"display: inline !important; float=
: none; background-color: transparent; color: rgb(34, 34, 34); font-family:=
 courier new,monospace; font-size: 13px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: l=
eft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit=
-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">a =3D b(*=
c);</span></font><br></div><div><br></div><div><font face=3D"courier new,mo=
nospace">a =3D b&amp;c;</font><br></div><div><font face=3D"courier new,mono=
space">a =3D &amp;c;</font></div><div><font face=3D"courier new,monospace">=
</font><br></div><div>etc.</div><div><font face=3D"courier new,monospace"><=
/font><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>despite looking almost exactly the same. Moreover,=
 this paper introduces a novel glyph (&amp;&amp;&gt;) which should in of it=
self have a reasonably high bar for adoption and I doubt that this kind of =
abbreviating syntax would gain consensus for the new token.=C2=A0</div></di=
v></blockquote><div><br></div><div><br></div><div>Fair enough - that is the=
 best I got. Alternatively a keyword might be used, but that&#39;s not that=
 easy either. Suggestions are always welcome=C2=A0</div><div><br></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div><br></div><div>Separately, I don&#39;t think replacing move() with a g=
lyph is particularly motivating. move() is quite a bit shorter than forward=
() because you don&#39;t need the extra type, and is pretty clear annotatio=
n for what the code is doing.<br></div></div></blockquote><div><br></div><d=
iv><br></div><div>I don&#39;t believe it&#39;s that simple. It is not about=
 just verbosity. Even if put the issue of two separate functions aside, the=
 use of a function itself is a <span style=3D"display: inline !important; f=
loat: none; background-color: transparent; color: rgb(34, 34, 34); font-fam=
ily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;">crutch</span>.=C2=A0</div><div><br></div><div>This =
is because the core language feature now depends on the standard library. T=
hink about it -<i> you cant use the language if you don&#39;t either use th=
e &#39;std&#39; </i>(library) helper functions or be &quot;a pro&quot; and =
use static_cast.<br></div><div>This is stating to look like C where you can=
&#39;t create objects without using the library.=C2=A0</div><div><br></div>=
<div>These things are not pretty to users new to c++.=C2=A0</div><div>They =
might get used to the funny type decoration (&amp;&amp;) but the use of som=
e special function to use them will not feel right. Things are even worse w=
hen are introduced to forward, where &quot;the same&quot; (in their eyes!) =
type, decorated with &amp;&amp;, must be used with yet another function.</d=
iv><div><br></div><div><br></div><div>Imagine - no operator*, but a library=
 std::deref. We are at the same place with rvalue references (be it in &quo=
t;forwarding from&quot; or standard).</div><div><br></div><div><br></div><d=
iv>My point is this - language level features must use language level tools=
.. Otherwise something went wrong in the design and we need to use a crutch.=
=C2=A0</div><div>My second point is the use of move and forward as separate=
 functions is redundant in de facto all cases.=C2=A0</div><div><br></div><d=
iv>So the number of tokens is not the primary concern.=C2=A0</div><div><br>=
</div><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/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8=
%40isocpp.org</a>.<br />

------=_Part_112324_1779233920.1528792533527--

------=_Part_112323_446883098.1528792533526--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Tue, 12 Jun 2018 11:44:47 +0200
Raw View
--00000000000069afca056e6eb8c5
Content-Type: text/plain; charset="UTF-8"

On Tue, 12 Jun 2018, 09:35 , <mihailnajdenov@gmail.com> wrote:

>
>
> On Monday, June 11, 2018 at 6:30:05 PM UTC+3, Barry Revzin wrote:
>>
>>
>>
>> On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, mihailn...@gmail.com
>> wrote:
>>>
>>> This is continuation of a previous topic
>>> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>>>
>>>
>>> Hello, I have written a proposal for merging `forward` and `move` behind
>>> a new postscript operator &&>
>>>
>>> This is the initial draft. Feedback is welcome.
>>>
>>> Thank You
>>> MihailNaydenov
>>>
>>
>>
>> As I mentioned in the previous thread, p0644 was discussed and ultimately
>> rejected in Albuquerque. I have no reason to believe that it was rejected
>> because the operator I proposed was *prefix* rather than *postfix*. All
>> of the concerns would apply just the same. For instance, from the
>> motivating example, this:
>>
>> func&&>(args&&>...);
>>
>> has *wildly different *meaning than this:
>>
>> func&&(args&&...);
>>
>>
>
> Yeah, but this is already true for * and & as well. The are not "almost
> the same", but exactly the same and used with wildly different meanings
> depending on the context.
>
> a = b*c;
> a = b(*c);
>
> a = b&c;
> a = &c;
>
> etc.
>
>
>
>> despite looking almost exactly the same. Moreover, this paper introduces
>> a novel glyph (&&>) which should in of itself have a reasonably high bar
>> for adoption and I doubt that this kind of abbreviating syntax would gain
>> consensus for the new token.
>>
>
>
> Fair enough - that is the best I got. Alternatively a keyword might be
> used, but that's not that easy either. Suggestions are always welcome
>
>
>
>>
>> Separately, I don't think replacing move() with a glyph is particularly
>> motivating. move() is quite a bit shorter than forward() because you don't
>> need the extra type, and is pretty clear annotation for what the code is
>> doing.
>>
>
>
> I don't believe it's that simple. It is not about just verbosity. Even if
> put the issue of two separate functions aside, the use of a function itself
> is a crutch.
>
> This is because the core language feature now depends on the standard
> library. Think about it -* you cant use the language if you don't either
> use the 'std' *(library) helper functions or be "a pro" and use
> static_cast.
> This is stating to look like C where you can't create objects without
> using the library.
>
> These things are not pretty to users new to c++.
> They might get used to the funny type decoration (&&) but the use of some
> special function to use them will not feel right. Things are even worse
> when are introduced to forward, where "the same" (in their eyes!) type,
> decorated with &&, must be used with yet another function.
>
>
> Imagine - no operator*, but a library std::deref. We are at the same place
> with rvalue references (be it in "forwarding from" or standard).
>
>
> My point is this - language level features must use language level tools.
> Otherwise something went wrong in the design and we need to use a crutch.
> My second point is the use of move and forward as separate functions is
> redundant in de facto all cases.
>
> So the number of tokens is not the primary concern.
>
>
Absolutely agree with this.


> --
> 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/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALvx3hYNWJTHoHFb7YZY9z7XktN3rvL4VJXdW8PuLNj%3DT9sKHQ%40mail.gmail.com.

--00000000000069afca056e6eb8c5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Tue, 12 Jun 2018, 09:35 , &lt;<a href=3D"mailto:mihailnajdenov@gmail.com=
">mihailnajdenov@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><br><br>On Monday, June 11, 2018 at 6:30:05 PM UTC+=
3, Barry Revzin wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><br><br>On Thursday, June 7, 2018 at 1:44:56 PM UTC-5, <a rel=3D"norefe=
rrer">mihailn...@gmail.com</a> wrote:<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>This is continuation of a <a href=3D"https://groups=
..google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" rel=
=3D"nofollow noreferrer" target=3D"_blank">previous topic</a>=C2=A0</div><d=
iv><br></div><div>Hello, I have written a proposal for merging `forward` an=
d `move` behind a new postscript operator &amp;&amp;&gt;</div><div><br></di=
v><div>This is the initial draft. Feedback is welcome.</div><div><br></div>=
<div>Thank You<br></div><div>MihailNaydenov=C2=A0</div></div></blockquote><=
div><br></div><div><br></div><div>As I mentioned in the previous thread, p0=
644 was discussed and ultimately rejected in Albuquerque. I have no reason =
to believe that it was rejected because the operator I proposed was <i>pref=
ix</i>=C2=A0rather than <i>postfix</i>. All of the concerns would apply jus=
t the same. For instance, from the motivating example, this:</div><div><br>=
</div><div><div style=3D"background-color:rgb(250,250,250);border-color:rgb=
(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><co=
de><div><font color=3D"#660066"><span style=3D"color:#000">func</span><span=
 style=3D"color:#660">&amp;&amp;&gt;(</span><span style=3D"color:#000">args=
</span><span style=3D"color:#660">&amp;&amp;&gt;...);</span></font></div></=
code></div><br>has <i>wildly different </i>meaning than this:</div><div><br=
></div><div><div style=3D"background-color:rgb(250,250,250);border-color:rg=
b(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><c=
ode><div><font color=3D"#660066"><span style=3D"color:#000">func</span><spa=
n style=3D"color:#660">&amp;&amp;(</span><span style=3D"color:#000">args</s=
pan><span style=3D"color:#660">&amp;&amp;...);</span></font></div></code></=
div><br></div></div></blockquote><div><br></div><div><br></div><div>Yeah, b=
ut this is already true for * and &amp; as well. The are not &quot;almost t=
he same&quot;, but exactly the same and used with wildly different meanings=
 depending on the context. =C2=A0=C2=A0</div><div><br></div><div><font face=
=3D"courier new,monospace">a =3D b*c;</font></div><div><font face=3D"courie=
r new,monospace"><span style=3D"display:inline!important;float:none;backgro=
und-color:transparent;color:rgb(34,34,34);font-family:courier new,monospace=
;font-size:13px;font-style:normal;font-variant:normal;font-weight:400;lette=
r-spacing:normal;text-align:left;text-decoration:none;text-indent:0px;text-=
transform:none;white-space:normal;word-spacing:0px">a =3D b(*c);</span></fo=
nt><br></div><div><br></div><div><font face=3D"courier new,monospace">a =3D=
 b&amp;c;</font><br></div><div><font face=3D"courier new,monospace">a =3D &=
amp;c;</font></div><div><font face=3D"courier new,monospace"></font><br></d=
iv><div>etc.</div><div><font face=3D"courier new,monospace"></font><br></di=
v><div>=C2=A0</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>despite looking almost exactly the same. Moreover, this paper introdu=
ces a novel glyph (&amp;&amp;&gt;) which should in of itself have a reasona=
bly high bar for adoption and I doubt that this kind of abbreviating syntax=
 would gain consensus for the new token.=C2=A0</div></div></blockquote><div=
><br></div><div><br></div><div>Fair enough - that is the best I got. Altern=
atively a keyword might be used, but that&#39;s not that easy either. Sugge=
stions are always welcome=C2=A0</div><div><br></div><div>=C2=A0</div><block=
quote 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><div>Sepa=
rately, I don&#39;t think replacing move() with a glyph is particularly mot=
ivating. move() is quite a bit shorter than forward() because you don&#39;t=
 need the extra type, and is pretty clear annotation for what the code is d=
oing.<br></div></div></blockquote><div><br></div><div><br></div><div>I don&=
#39;t believe it&#39;s that simple. It is not about just verbosity. Even if=
 put the issue of two separate functions aside, the use of a function itsel=
f is a <span style=3D"display:inline!important;float:none;background-color:=
transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&quot;Helveti=
ca&quot;,sans-serif;font-size:13px;font-style:normal;font-variant:normal;fo=
nt-weight:400;letter-spacing:normal;text-align:left;text-decoration:none;te=
xt-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">crut=
ch</span>.=C2=A0</div><div><br></div><div>This is because the core language=
 feature now depends on the standard library. Think about it -<i> you cant =
use the language if you don&#39;t either use the &#39;std&#39; </i>(library=
) helper functions or be &quot;a pro&quot; and use static_cast.<br></div><d=
iv>This is stating to look like C where you can&#39;t create objects withou=
t using the library.=C2=A0</div><div><br></div><div>These things are not pr=
etty to users new to c++.=C2=A0</div><div>They might get used to the funny =
type decoration (&amp;&amp;) but the use of some special function to use th=
em will not feel right. Things are even worse when are introduced to forwar=
d, where &quot;the same&quot; (in their eyes!) type, decorated with &amp;&a=
mp;, must be used with yet another function.</div><div><br></div><div><br><=
/div><div>Imagine - no operator*, but a library std::deref. We are at the s=
ame place with rvalue references (be it in &quot;forwarding from&quot; or s=
tandard).</div><div><br></div><div><br></div><div>My point is this - langua=
ge level features must use language level tools. Otherwise something went w=
rong in the design and we need to use a crutch.=C2=A0</div><div>My second p=
oint is the use of move and forward as separate functions is redundant in d=
e facto all cases.=C2=A0</div><div><br></div><div>So the number of tokens i=
s not the primary concern.=C2=A0</div><div><br></div><div></div></div></blo=
ckquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">Absolutel=
y agree with this.=C2=A0</div><div dir=3D"auto"><br></div><div dir=3D"auto"=
><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/06c82afe-0630-47c8-bb38-2fe3c1e9c6d8%40isocpp.org</a>.<br>
</blockquote></div></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/CALvx3hYNWJTHoHFb7YZY9z7XktN3rvL4VJXd=
W8PuLNj%3DT9sKHQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hYNWJTHoH=
Fb7YZY9z7XktN3rvL4VJXdW8PuLNj%3DT9sKHQ%40mail.gmail.com</a>.<br />

--00000000000069afca056e6eb8c5--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 12 Jun 2018 06:57:18 -0700 (PDT)
Raw View
------=_Part_62666_518744281.1528811838481
Content-Type: multipart/alternative;
 boundary="----=_Part_62667_1358351872.1528811838482"

------=_Part_62667_1358351872.1528811838482
Content-Type: text/plain; charset="UTF-8"

On Tuesday, June 12, 2018 at 4:35:33 AM UTC-4, mihailn...@gmail.com wrote:
>
> I don't believe it's that simple. It is not about just verbosity. Even if
> put the issue of two separate functions aside, the use of a function itself
> is a crutch.
>
> This is because the core language feature now depends on the standard
> library. Think about it -* you cant use the language if you don't either
> use the 'std' *(library) helper functions or be "a pro" and use
> static_cast.
>

You've kind of disproved your first statement, since move and forward
*don't* depend on the library. You can use a `static_cast`, which is a part
of the language. The library functions are *helpers*; they make the
`static_cast` more palatable, but they're not required.

Furthermore, I dispute the characterization of move and forward with
respect to the standard library. Movement has always been a function of the
*implementation* of a type, not of the language. Rvalue references are
needed to make movement possible, but movement only happens if the type
properly implements the concept.

The default move constructor is a prime example of this; by default, it's a
*copy* constructor. Even for pointers, where one might conceivably by
default null out the old pointer.

The language and the library (that is, the compiler and the source code)
have always been intertwined when it comes to move.

This is stating to look like C where you can't create objects without using
> the library.
>
> These things are not pretty to users new to c++.
> They might get used to the funny type decoration (&&) but the use of some
> special function to use them will not feel right. Things are even worse
> when are introduced to forward, where "the same" (in their eyes!) type,
> decorated with &&, must be used with yet another function.
>

The sooner users learn that it's *not* "the same" despite all appearances,
the better. Forwarding references are different from rvalue references, and
users should not be encouraged to forget this fact.

Imagine - no operator*, but a library std::deref. We are at the same place
> with rvalue references (be it in "forwarding from" or standard).
>

This goes back to that difference I spoke of earlier. Without giving
pointers an operator for deference, your hypothetical `std::deref` is
*required* to use a pointer. By contrast, move and forwarding don't
*require* the use of the standard library functions.

My point is this - language level features must use language level tools.
> Otherwise something went wrong in the design and we need to use a crutch.
>

C++ is not a language that can be divorced from its standard library.
Indeed, C++ as a language *prides* itself on providing low-level mechanisms
such that it can use library components to do what other languages use
grammar for. So there's nothing a priori wrong with using helper functions
for language features.

The question that needs to be asked is whether the resulting code is
difficult to write and/or is readable.

Your `std::deref` analogy is bad because it makes an extremely common
operation *gigantic*, relative to the importance of what's going on. It's
not a matter of language vs. library; it's a matter of the readability of
the resulting code.

Though I rather suspect that if we had such a thing, there would be a lot
less pointer use ;)

Every use of `std::move` is readable. The word tells you what's going on;
you don't have to guess or wonder what a symbol means. Even the newest of
newbies, once they understand what `std::` means, can at least understand
that something in the given operation is being moved (even though
technically it isn't yet).

`std::move` is short. It pokes you in the eye a bit, but that's a good
thing. Movement can be dangerous, so poking you in the eye a bit is good.
Thus, making it shorter is not necessarily good.

The use of `std::forward` is far less readable. Having to supply a template
parameter creates a great deal of noise around something that is
conceptually simple. Using `decltype<varname>` is an idiom users can use,
but it's hardly simple.

As such, having a shorter version of `std::forward` makes sense. It will
improve the usability of the feature, and it creates no ambiguity.

Merging this with `std::move` doesn't improve things materially.

My second point is the use of move and forward as separate functions is
> redundant in de facto all cases.
>
> So the number of tokens is not the primary concern.
>

--
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/5a7cab12-ef19-4142-9d24-8e3ebeab74e3%40isocpp.org.

------=_Part_62667_1358351872.1528811838482
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, June 12, 2018 at 4:35:33 AM UTC-4, mihailn...@=
gmail.com 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"><div></div><div>I don&#39;t believe it&#39;s that simple. It is not abou=
t just verbosity. Even if put the issue of two separate functions aside, th=
e use of a function itself is a <span style=3D"display:inline!important;flo=
at:none;background-color:transparent;color:rgb(34,34,34);font-family:&quot;=
Arial&quot;,&quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:norm=
al;font-variant:normal;font-weight:400;letter-spacing:normal;text-align:lef=
t;text-decoration:none;text-indent:0px;text-transform:none;white-space:norm=
al;word-spacing:0px">crutch</span>.=C2=A0</div><div><br></div><div>This is =
because the core language feature now depends on the standard library. Thin=
k about it -<i> you cant use the language if you don&#39;t either use the &=
#39;std&#39; </i>(library) helper functions or be &quot;a pro&quot; and use=
 static_cast.<br></div></div></blockquote><div><br></div><div>You&#39;ve ki=
nd of disproved your first statement, since move and forward <i>don&#39;t</=
i> depend on the library. You can use a `static_cast`, which is a part of t=
he language. The library functions are <i>helpers</i>; they make the `stati=
c_cast` more palatable, but they&#39;re not required.<br></div><div><br></d=
iv><div>Furthermore, I dispute the characterization of move and forward wit=
h respect to the standard library. Movement has always been a function of t=
he <i>implementation</i> of a type, not of the language. Rvalue references =
are needed to make movement possible, but movement only happens if the type=
 properly implements the concept.</div><div><br></div><div>The default move=
 constructor is a prime example of this; by default, it&#39;s a <i>copy</i>=
 constructor. Even for pointers, where one might conceivably by default nul=
l out the old pointer.</div><div><br></div><div>The language and the librar=
y (that is, the compiler and the source code) have always been intertwined =
when it comes to move.<br></div><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div></div><div>This is stating to look l=
ike C where you can&#39;t create objects without using the library.=C2=A0</=
div><div><br></div><div>These things are not pretty to users new to c++.=C2=
=A0</div><div>They might get used to the funny type decoration (&amp;&amp;)=
 but the use of some special function to use them will not feel right. Thin=
gs are even worse when are introduced to forward, where &quot;the same&quot=
; (in their eyes!) type, decorated with &amp;&amp;, must be used with yet a=
nother function.</div></div></blockquote><div><br></div><div>The sooner use=
rs learn that it&#39;s <i>not</i> &quot;the same&quot; despite all appearan=
ces, the better. Forwarding references are different from rvalue references=
, and users should not be encouraged to forget this fact.<br></div><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><=
/div><div>Imagine - no operator*, but a library std::deref. We are at the s=
ame place with rvalue references (be it in &quot;forwarding from&quot; or s=
tandard).</div></div></blockquote><div><br></div><div>This goes back to tha=
t difference I spoke of earlier. Without giving pointers an operator for de=
ference, your hypothetical `std::deref` is <i>required</i> to use a pointer=
.. By contrast, move and forwarding don&#39;t <i>require</i> the use of the =
standard library functions.</div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div></div><div>My point is this - langu=
age level features must use language level tools. Otherwise something went =
wrong in the design and we need to use a crutch.</div></div></blockquote><d=
iv><br></div><div>C++ is not a language that can be divorced from its stand=
ard library. Indeed, C++ as a language <i>prides</i> itself on providing lo=
w-level mechanisms such that it can use library components to do what other=
 languages use grammar for. So there&#39;s nothing a priori wrong with usin=
g helper functions for language features.<br></div><div><br></div><div>The =
question that needs to be asked is whether the resulting code is difficult =
to write and/or is readable.</div><div><br></div><div>Your `std::deref` ana=
logy is bad because it makes an extremely common operation <i>gigantic</i>,=
 relative to the importance of what&#39;s going on. It&#39;s not a matter o=
f language vs. library; it&#39;s a matter of the readability of the resulti=
ng code.</div><div><br></div><div>Though I rather suspect that if we had su=
ch a thing, there would be a lot less pointer use ;)<br></div><div><br></di=
v><div>Every use of `std::move` is readable. The word tells you what&#39;s =
going on; you don&#39;t have to guess or wonder what a symbol means. Even t=
he newest of newbies, once they understand what `std::` means, can at least=
 understand that something in the given operation is being moved (even thou=
gh technically it isn&#39;t yet).</div><div><br></div><div>`std::move` is s=
hort. It pokes you in the eye a bit, but that&#39;s a good thing. Movement =
can be dangerous, so poking you in the eye a bit is good. Thus, making it s=
horter is not necessarily good.<br></div><div><br></div><div>The use of `st=
d::forward` is far less readable. Having to supply a template parameter cre=
ates a great deal of noise around something that is conceptually simple. Us=
ing `decltype&lt;varname&gt;` is an idiom users can use, but it&#39;s hardl=
y simple.<br></div><div><br></div><div>As such, having a shorter version of=
 `std::forward` makes sense. It will improve the usability of the feature, =
and it creates no ambiguity.</div><div><br></div><div>Merging this with `st=
d::move` doesn&#39;t improve things materially.<br></div><div><br></div><bl=
ockquote 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>My second p=
oint is the use of move and forward as separate functions is redundant in d=
e facto all cases.=C2=A0</div><div><br></div><div>So the number of tokens i=
s not the primary concern.</div></div></blockquote></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/5a7cab12-ef19-4142-9d24-8e3ebeab74e3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5a7cab12-ef19-4142-9d24-8e3ebeab74e3=
%40isocpp.org</a>.<br />

------=_Part_62667_1358351872.1528811838482--

------=_Part_62666_518744281.1528811838481--

.


Author: mihailnajdenov@gmail.com
Date: Tue, 12 Jun 2018 11:50:20 -0700 (PDT)
Raw View
------=_Part_112896_1529083886.1528829420243
Content-Type: multipart/alternative;
 boundary="----=_Part_112897_525381695.1528829420243"

------=_Part_112897_525381695.1528829420243
Content-Type: text/plain; charset="UTF-8"



On Tuesday, June 12, 2018 at 4:57:18 PM UTC+3, Nicol Bolas wrote:
>
> On Tuesday, June 12, 2018 at 4:35:33 AM UTC-4, mihailn...@gmail.com wrote:
>>
>> I don't believe it's that simple. It is not about just verbosity. Even if
>> put the issue of two separate functions aside, the use of a function itself
>> is a crutch.
>>
>> This is because the core language feature now depends on the standard
>> library. Think about it -* you cant use the language if you don't either
>> use the 'std' *(library) helper functions or be "a pro" and use
>> static_cast.
>>
>
> You've kind of disproved your first statement, since move and forward
> *don't* depend on the library. You can use a `static_cast`, which is a
> part of the language. The library functions are *helpers*; they make the
> `static_cast` more palatable, but they're not required.
>

You can't teach baseline C++ without introducing std. Back in the day that
was possible. You can't point out the features of C++, compared to C,
without std.

For me that's design deficiency, making movement looks like an after
thought. Yes it is, but there is no reason to be like that forever.

And no one will ever convince someone static_cast was ever considered to be
the interface to use.


>
> Furthermore, I dispute the characterization of move and forward with
> respect to the standard library. Movement has always been a function of the
> *implementation* of a type, not of the language. Rvalue references are
> needed to make movement possible, but movement only happens if the type
> properly implements the concept.
>


Not semantically. Movement and forwarding is there semantically no matter
if it happens or not. If it implemented by the type or not.



>
> The default move constructor is a prime example of this; by default, it's
> a *copy* constructor. Even for pointers, where one might conceivably by
> default null out the old pointer.
>
> The language and the library (that is, the compiler and the source code)
> have always been intertwined when it comes to move.
>


How is the compiler the library?



>
> This is stating to look like C where you can't create objects without
>> using the library.
>>
>> These things are not pretty to users new to c++.
>> They might get used to the funny type decoration (&&) but the use of some
>> special function to use them will not feel right. Things are even worse
>> when are introduced to forward, where "the same" (in their eyes!) type,
>> decorated with &&, must be used with yet another function.
>>
>
> The sooner users learn that it's *not* "the same" despite all
> appearances, the better. Forwarding references are different from rvalue
> references, and users should not be encouraged to forget this fact.
>


I really doubt the way to teach them the diffs is to have two separate
functions, especially that if they get it wrong, the will shoot themselves
in the foot with no warning.



>
> Imagine - no operator*, but a library std::deref. We are at the same place
>> with rvalue references (be it in "forwarding from" or standard).
>>
>
> This goes back to that difference I spoke of earlier. Without giving
> pointers an operator for deference, your hypothetical `std::deref` is
> *required* to use a pointer. By contrast, move and forwarding don't
> *require* the use of the standard library functions.
>
> My point is this - language level features must use language level tools.
>> Otherwise something went wrong in the design and we need to use a crutch.
>>
>
> C++ is not a language that can be divorced from its standard library.
> Indeed, C++ as a language *prides* itself on providing low-level
> mechanisms such that it can use library components to do what other
> languages use grammar for. So there's nothing a priori wrong with using
> helper functions for language features.
>


Nothing wrong to implement features as library and to have library and
language level access. But the other way around does not feel right.

Not that is a cardinal sin, but it is not like there is nothing wrong with
it.



>
> The question that needs to be asked is whether the resulting code is
> difficult to write and/or is readable.
>
> Your `std::deref` analogy is bad because it makes an extremely common
> operation *gigantic*, relative to the importance of what's going on. It's
> not a matter of language vs. library; it's a matter of the readability of
> the resulting code.
>
> Though I rather suspect that if we had such a thing, there would be a lot
> less pointer use ;)
>
> Every use of `std::move` is readable. The word tells you what's going on;
> you don't have to guess or wonder what a symbol means. Even the newest of
> newbies, once they understand what `std::` means, can at least understand
> that something in the given operation is being moved (even though
> technically it isn't yet).
>
> `std::move` is short. It pokes you in the eye a bit, but that's a good
> thing. Movement can be dangerous, so poking you in the eye a bit is good.
> Thus, making it shorter is not necessarily good.
>

> The use of `std::forward` is far less readable. Having to supply a
> template parameter creates a great deal of noise around something that is
> conceptually simple. Using `decltype<varname>` is an idiom users can use,
> but it's hardly simple.
>
> As such, having a shorter version of `std::forward` makes sense. It will
> improve the usability of the feature, and it creates no ambiguity.
>
> Merging this with `std::move` doesn't improve things materially.
>


This is entirely the view of the professional. Nothing wrong with it.
However streamlining C++ in any way, I do believe, improve things
materially.

And even for a profession some cases are tough and/or fragile.


>
> My second point is the use of move and forward as separate functions is
>> redundant in de facto all cases.
>>
>> So the number of tokens is not the primary concern.
>>
>

--
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/ec92e0eb-995e-46c1-a113-d878134b4bb1%40isocpp.org.

------=_Part_112897_525381695.1528829420243
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Tuesday, June 12, 2018 at 4:57:18 PM UTC+3, Nic=
ol 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, June 12, 2018 at 4:35:33 AM UTC-4, <a>mihailn...@gmail.com</a=
> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div=
><div>I don&#39;t believe it&#39;s that simple. It is not about just verbos=
ity. Even if put the issue of two separate functions aside, the use of a fu=
nction itself is a <span style=3D"display:inline!important;float:none;backg=
round-color:transparent;color:rgb(34,34,34);font-family:&quot;Arial&quot;,&=
quot;Helvetica&quot;,sans-serif;font-size:13px;font-style:normal;font-varia=
nt:normal;font-weight:400;letter-spacing:normal;text-align:left;text-decora=
tion:none;text-indent:0px;text-transform:none;white-space:normal;word-spaci=
ng:0px">crutch</span>.=C2=A0</div><div><br></div><div>This is because the c=
ore language feature now depends on the standard library. Think about it -<=
i> you cant use the language if you don&#39;t either use the &#39;std&#39; =
</i>(library) helper functions or be &quot;a pro&quot; and use static_cast.=
<br></div></div></blockquote><div><br></div><div>You&#39;ve kind of disprov=
ed your first statement, since move and forward <i>don&#39;t</i> depend on =
the library. You can use a `static_cast`, which is a part of the language. =
The library functions are <i>helpers</i>; they make the `static_cast` more =
palatable, but they&#39;re not required.<br></div></div></blockquote><div><=
br></div><div>You can&#39;t teach baseline C++ without introducing std. Bac=
k in the day that was possible. You can&#39;t point out the features of C++=
, compared to C, without std.=C2=A0</div><div><br></div><div>For me that&#3=
9;s design deficiency, making movement looks like an after thought. Yes it =
is, but there is no reason to be like that forever.</div><div><br></div><di=
v>And no one will ever convince someone static_cast was ever considered to =
be the interface to use.</div><div>=C2=A0</div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div></div><div><br></div><div>Furthermor=
e, I dispute the characterization of move and forward with respect to the s=
tandard library. Movement has always been a function of the <i>implementati=
on</i> of a type, not of the language. Rvalue references are needed to make=
 movement possible, but movement only happens if the type properly implemen=
ts the concept.</div></div></blockquote><div><br></div><div><br></div><div>=
Not semantically. Movement and forwarding is there semantically no matter i=
f it happens or not. If it implemented by the type or not.</div><div><br></=
div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><br></div><div>The default move constructor is a prime exampl=
e of this; by default, it&#39;s a <i>copy</i> constructor. Even for pointer=
s, where one might conceivably by default null out the old pointer.</div><d=
iv><br></div><div>The language and the library (that is, the compiler and t=
he source code) have always been intertwined when it comes to move.<br></di=
v></div></blockquote><div><br></div><div><br></div><div>How is the compiler=
 the library?=C2=A0</div><div><b></b><i></i><u></u><sub></sub><sup></sup><s=
trike></strike><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></div><div><br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><div>This is stating to loo=
k like C where you can&#39;t create objects without using the library.=C2=
=A0</div><div><br></div><div>These things are not pretty to users new to c+=
+.=C2=A0</div><div>They might get used to the funny type decoration (&amp;&=
amp;) but the use of some special function to use them will not feel right.=
 Things are even worse when are introduced to forward, where &quot;the same=
&quot; (in their eyes!) type, decorated with &amp;&amp;, must be used with =
yet another function.</div></div></blockquote><div><br></div><div>The soone=
r users learn that it&#39;s <i>not</i> &quot;the same&quot; despite all app=
earances, the better. Forwarding references are different from rvalue refer=
ences, and users should not be encouraged to forget this fact.<br></div></d=
iv></blockquote><div><br></div><div><br></div><div>I really doubt the way t=
o teach them the diffs is to have two separate functions, especially that i=
f they get it wrong, the will shoot themselves in the foot with no warning.=
=C2=A0</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div></div><div><br></div><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></div><div>Imagine - no operat=
or*, but a library std::deref. We are at the same place with rvalue referen=
ces (be it in &quot;forwarding from&quot; or standard).</div></div></blockq=
uote><div><br></div><div>This goes back to that difference I spoke of earli=
er. Without giving pointers an operator for deference, your hypothetical `s=
td::deref` is <i>required</i> to use a pointer. By contrast, move and forwa=
rding don&#39;t <i>require</i> the use of the standard library functions.</=
div><div><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></div><div>My point is this - language level features must use langua=
ge level tools. Otherwise something went wrong in the design and we need to=
 use a crutch.</div></div></blockquote><div><br></div><div>C++ is not a lan=
guage that can be divorced from its standard library. Indeed, C++ as a lang=
uage <i>prides</i> itself on providing low-level mechanisms such that it ca=
n use library components to do what other languages use grammar for. So the=
re&#39;s nothing a priori wrong with using helper functions for language fe=
atures.<br></div></div></blockquote><div><br></div><div><br></div><div><spa=
n style=3D"display: inline !important; float: none; background-color: trans=
parent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvet=
ica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: no=
rmal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: lef=
t; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-t=
ext-stroke-width: 0px; white-space: normal; word-spacing: 0px;">Nothing wro=
ng to implement features as library and to have library and language level =
access. But the other way around does not feel right.=C2=A0</span></div><di=
v><span style=3D"display: inline !important; float: none; background-color:=
 transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varia=
nt: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-alig=
n: left; text-decoration: none; text-indent: 0px; text-transform: none; -we=
bkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br><=
/span></div><div><span style=3D"display: inline !important; float: none; ba=
ckground-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: nor=
mal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphan=
s: 2; text-align: left; text-decoration: none; text-indent: 0px; text-trans=
form: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spaci=
ng: 0px;">Not that is a cardinal sin, but it is not like there is nothing w=
rong with it. =C2=A0</span></div><div><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></div><div><br></d=
iv><div>The question that needs to be asked is whether the resulting code i=
s difficult to write and/or is readable.</div><div><br></div><div>Your `std=
::deref` analogy is bad because it makes an extremely common operation <i>g=
igantic</i>, relative to the importance of what&#39;s going on. It&#39;s no=
t a matter of language vs. library; it&#39;s a matter of the readability of=
 the resulting code.</div><div><br></div><div>Though I rather suspect that =
if we had such a thing, there would be a lot less pointer use ;)<br></div><=
div><br></div><div>Every use of `std::move` is readable. The word tells you=
 what&#39;s going on; you don&#39;t have to guess or wonder what a symbol m=
eans. Even the newest of newbies, once they understand what `std::` means, =
can at least understand that something in the given operation is being move=
d (even though technically it isn&#39;t yet).</div><div><br></div><div>`std=
::move` is short. It pokes you in the eye a bit, but that&#39;s a good thin=
g. Movement can be dangerous, so poking you in the eye a bit is good. Thus,=
 making it shorter is not necessarily good.<br></div></div></blockquote><bl=
ockquote 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>=
<br></div><div>The use of `std::forward` is far less readable. Having to su=
pply a template parameter creates a great deal of noise around something th=
at is conceptually simple. Using `decltype&lt;varname&gt;` is an idiom user=
s can use, but it&#39;s hardly simple.<br></div><div><br></div><div>As such=
, having a shorter version of `std::forward` makes sense. It will improve t=
he usability of the feature, and it creates no ambiguity.</div><div><br></d=
iv><div>Merging this with `std::move` doesn&#39;t improve things materially=
..<br></div></div></blockquote><div><br></div><div><br></div><div>This is en=
tirely the view of the professional. Nothing wrong with it. However streaml=
ining C++ in any way, I do believe, improve <span style=3D"display: inline =
!important; float: none; background-color: transparent; color: rgb(34, 34, =
34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-=
size: 13px; font-style: normal; font-variant: normal; font-weight: 400; let=
ter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; t=
ext-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whit=
e-space: normal; word-spacing: 0px;">things materially.</span></div><div><s=
pan style=3D"display: inline !important; float: none; background-color: tra=
nsparent; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helv=
etica&quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: =
normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: l=
eft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit=
-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></spa=
n></div><div><span style=3D"display: inline !important; float: none; backgr=
ound-color: transparent; color: rgb(34, 34, 34); font-family: &quot;Arial&q=
uot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal;=
 font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2=
; text-align: left; text-decoration: none; text-indent: 0px; text-transform=
: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: =
0px;">And even for a profession some cases are tough and/or fragile.=C2=A0<=
/span></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><div></div><div><br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>My second point is the use of move and forward=
 as separate functions is redundant in de facto all cases.=C2=A0</div><div>=
<br></div><div>So the number of tokens is not the primary concern.</div></d=
iv></blockquote></div></blockquote></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/ec92e0eb-995e-46c1-a113-d878134b4bb1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ec92e0eb-995e-46c1-a113-d878134b4bb1=
%40isocpp.org</a>.<br />

------=_Part_112897_525381695.1528829420243--

------=_Part_112896_1529083886.1528829420243--

.


Author: mihailnajdenov@gmail.com
Date: Mon, 18 Jun 2018 06:01:14 -0700 (PDT)
Raw View
------=_Part_20102_1303376344.1529326874722
Content-Type: multipart/alternative;
 boundary="----=_Part_20103_37306184.1529326874722"

------=_Part_20103_37306184.1529326874722
Content-Type: text/plain; charset="UTF-8"

Updated the proposal with the comments thus far.



On Thursday, June 7, 2018 at 9:44:56 PM UTC+3, mihailn...@gmail.com wrote:
>
> This is continuation of a previous topic
> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>
>
> Hello, I have written a proposal for merging `forward` and `move` behind a
> new postscript operator &&>
>
> This is the initial draft. Feedback is welcome.
>
> Thank You
> MihailNaydenov
>

--
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/3ecf180f-46c5-49ea-a3f2-ef45226cb23c%40isocpp.org.

------=_Part_20103_37306184.1529326874722
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Updated the proposal with the comments thus far.</div=
><div><br></div><div><br></div><br>On Thursday, June 7, 2018 at 9:44:56 PM =
UTC+3, mihailn...@gmail.com 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"><div>This is continuation of a <a onmousedown=3D"thi=
s.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kd=
t1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;" onclick=3D"this.href=3D&#39;https=
://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbD=
QAJ&#39;;return true;" href=3D"https://groups.google.com/a/isocpp.org/d/msg=
/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" target=3D"_blank" rel=3D"nofollow"=
>previous topic</a>=C2=A0</div><div><br></div><div>Hello, I have written a =
proposal for merging `forward` and `move` behind a new postscript operator =
&amp;&amp;&gt;</div><div><br></div><div>This is the initial draft. Feedback=
 is welcome.</div><div><br></div><div>Thank You<br></div><div>MihailNaydeno=
v=C2=A0</div></div></blockquote></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/3ecf180f-46c5-49ea-a3f2-ef45226cb23c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3ecf180f-46c5-49ea-a3f2-ef45226cb23c=
%40isocpp.org</a>.<br />

------=_Part_20103_37306184.1529326874722--

------=_Part_20102_1303376344.1529326874722
Content-Type: text/html; charset=UTF-8; name=uniform-move-and-forward.html
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=uniform-move-and-forward.html
X-Attachment-Id: 515116fd-6d82-45cc-be03-37f2088edd75
Content-ID: <515116fd-6d82-45cc-be03-37f2088edd75>

=EF=BB=BF<!DOCTYPE html>
<html>

<head>
  <meta charset=3D"utf-8">
  <meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=3D=
1.0">
  <title>uniform</title>
  <link rel=3D"stylesheet" href=3D"https://stackedit.io/style.css" />
</head>

<body class=3D"stackedit">
  <div class=3D"stackedit__html"><p>Document number: xxx1<br>
Date: 2018-7-06<br>
Audience: EWG<br>
Reply-To: Mihail Naydenov &lt;mihailnajdenov at gmail dot com&gt;</p>
<hr>
<h1 align=3D"center">Uniform 'move' and 'forward' syntax</h1>
<h2 id=3D"intro">Intro</h2>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">auto</span> cally <span class=3D"token operator">=3D</s=
pan> <span class=3D"token punctuation">[</span><span class=3D"token punctua=
tion">]</span><span class=3D"token punctuation">(</span><span class=3D"toke=
n keyword">auto</span><span class=3D"token operator">&amp;&amp;</span> func=
<span class=3D"token punctuation">,</span> <span class=3D"token keyword">au=
to</span><span class=3D"token operator">&amp;&amp;</span><span class=3D"tok=
en punctuation">.</span><span class=3D"token punctuation">.</span><span cla=
ss=3D"token punctuation">.</span> y<span class=3D"token punctuation">)</spa=
n> =20
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">return</span> func<span class=3D"token oper=
ator">&amp;&amp;</span><span class=3D"token operator">&gt;</span><span clas=
s=3D"token punctuation">(</span>args<span class=3D"token operator">&amp;&am=
p;</span><span class=3D"token operator">&gt;</span><span class=3D"token pun=
ctuation">.</span><span class=3D"token punctuation">.</span><span class=3D"=
token punctuation">.</span><span class=3D"token punctuation">)</span><span =
class=3D"token punctuation">;</span> <span class=3D"token comment">//&lt; f=
orward without extreme verbosity</span>
<span class=3D"token punctuation">}</span>
</code></pre>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp">Class<span=
 class=3D"token operator">::</span><span class=3D"token function">Class</sp=
an><span class=3D"token punctuation">(</span>string<span class=3D"token ope=
rator">&amp;&amp;</span> name<span class=3D"token punctuation">,</span> fun=
ction<span class=3D"token operator">&amp;&amp;</span> func<span class=3D"to=
ken punctuation">)</span>
<span class=3D"token operator">:</span> <span class=3D"token function">_nam=
e</span><span class=3D"token punctuation">(</span>name<span class=3D"token =
operator">&amp;&amp;</span><span class=3D"token operator">&gt;</span><span =
class=3D"token punctuation">)</span><span class=3D"token punctuation">,</sp=
an> <span class=3D"token function">_func</span><span class=3D"token punctua=
tion">(</span>func<span class=3D"token operator">&amp;&amp;</span><span cla=
ss=3D"token operator">&gt;</span><span class=3D"token punctuation">)</span>=
 <span class=3D"token comment">//&lt; move with natural syntax</span>
<span class=3D"token punctuation">{</span><span class=3D"token punctuation"=
>}</span>
</code></pre>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">decltype</span><span class=3D"token punctuation">(</spa=
n><span class=3D"token keyword">auto</span><span class=3D"token punctuation=
">)</span> <span class=3D"token function">insert</span><span class=3D"token=
 punctuation">(</span>string<span class=3D"token operator">&amp;&amp;</span=
> name<span class=3D"token punctuation">,</span> <span class=3D"token keywo=
rd">auto</span><span class=3D"token operator">&amp;&amp;</span> func<span c=
lass=3D"token punctuation">)</span> =20
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">return</span> acts<span class=3D"token punc=
tuation">.</span><span class=3D"token function">emplace</span><span class=
=3D"token punctuation">(</span>name<span class=3D"token operator">&amp;&amp=
;</span><span class=3D"token operator">&gt;</span><span class=3D"token punc=
tuation">,</span> func<span class=3D"token operator">&amp;&amp;</span><span=
 class=3D"token operator">&gt;</span><span class=3D"token punctuation">)</s=
pan><span class=3D"token punctuation">;</span> <span class=3D"token comment=
">//&lt; no uncertainty when to use each one</span>
<span class=3D"token punctuation">}</span>
</code></pre>
<pre class=3D" language-cpp"><code class=3D"prism  language-cpp"><span clas=
s=3D"token keyword">template</span><span class=3D"token operator">&lt;</spa=
n><span class=3D"token keyword">class</span><span class=3D"token punctuatio=
n">.</span><span class=3D"token punctuation">.</span><span class=3D"token p=
unctuation">.</span> T<span class=3D"token operator">&gt;</span>
<span class=3D"token keyword">class</span> <span class=3D"token class-name"=
>Wrapper</span> =20
<span class=3D"token punctuation">{</span>
  <span class=3D"token keyword">decltype</span><span class=3D"token punctua=
tion">(</span><span class=3D"token keyword">auto</span><span class=3D"token=
 punctuation">)</span> <span class=3D"token keyword">operator</span><span c=
lass=3D"token punctuation">(</span><span class=3D"token punctuation">)</spa=
n><span class=3D"token punctuation">(</span>T<span class=3D"token operator"=
>&amp;&amp;</span><span class=3D"token punctuation">.</span><span class=3D"=
token punctuation">.</span><span class=3D"token punctuation">.</span> val<s=
pan class=3D"token punctuation">)</span>
  <span class=3D"token punctuation">{</span>
    <span class=3D"token keyword">return</span> <span class=3D"token functi=
on">call_stub</span><span class=3D"token punctuation">(</span>val<span clas=
s=3D"token operator">&amp;&amp;</span><span class=3D"token operator">&gt;</=
span><span class=3D"token punctuation">.</span><span class=3D"token punctua=
tion">.</span><span class=3D"token punctuation">.</span><span class=3D"toke=
n punctuation">)</span><span class=3D"token punctuation">;</span> <span cla=
ss=3D"token comment">//&lt; tricky case becomes trivial</span>
  <span class=3D"token punctuation">}</span>
<span class=3D"token punctuation">}</span>
</code></pre>
<p>This proposal introduces a dedicated postscript operator, which handles =
<code>std::forward</code> and <code>std::move</code> in a unified fashion, =
behind a single, terse syntax.</p>
<h2 id=3D"motivation">Motivation</h2>
<h3 id=3D"motivation-for-uniformity">Motivation for uniformity</h3>
<p>In the decade of use of <code>move</code> and <code>forward</code> three=
 observation can be made:</p>
<ul>
<li>One uses <em>either</em> <code>move</code> <em>or</em> <code>forward</c=
ode>;</li>
<li>It is always clear when to use each, using one in the place of the othe=
r is <em>in practice</em> always wrong;</li>
<li>The results of the operations are <em>effectively</em> the same - objec=
t if passed along and its identifier should not be further used as it is;</=
li>
</ul>
<p>The first two observations lead to the conclusion, usage of the two func=
tions is <em>statically deterministic</em> and not bound to a decision maki=
ng.<br>
The third observation tell us, there is <em>underlying concept</em>, connec=
ting both operations to a common base - the concept of passing-along and gi=
ving up usage rights over an object.</p>
<p>This all lead us to believe, it is possible to come up with a more gener=
al operation, which combines the currently used two separate operations. Do=
ing so will have multiple positive benefits:</p>
<ul>
<li><strong>Less fragile code</strong></li>
</ul>
<pre><code>template&lt;class F&gt;
decltype(auto) insert(string&amp;&amp; name, F&amp;&amp; func) =20
{
 return actions.emplace(std::move(name), std::forward&lt;F&gt;(func));=20
}
</code></pre>
<p>In the above example, if the user decides to =E2=80=9Cupgrade=E2=80=9D t=
he function to make the <code>name</code> argument a templated one, he <em>=
must</em> remember to also change <code>move</code> to <code>forward</code>=
 or risk either confusion for the people reading the code or unexpected beh=
avior.</p>
<p>With the current proposal the user (or tools), can change the function s=
ignature and the code will still behave correctly in de-facto all cases.</p=
>
<ul>
<li><strong>Some cases are tricky</strong></li>
</ul>
<pre><code>template&lt;class... T&gt;
class Wrapper =20
{
  decltype(auto) operator()(T&amp;&amp;... val) //&lt; not a forwarding ref=
erence
  {
    return call_stub(val&amp;&amp;&gt;...); //&lt; T will be reference, we =
want collapsing - forwarard
  }
}
</code></pre>
<p>The decision to use either <code>move</code> or <code>forward</code> is =
not always that obvious. It will be nice to have an operation that =E2=80=
=9Cjust works=E2=80=9D.</p>
<ul>
<li>
<p><strong>One less thing to learn and remember</strong><br>
The distinction b/w <code>forward</code> and <code>move</code> is subtle, a=
rguably it is an =E2=80=9Cadvanced understanding=E2=80=9D.<br>
However, this understanding alone does <em>not</em> contribute to writing b=
etter code. The tools to write better code are rvalue references and =E2=80=
=9Cforwarding references=E2=80=9D, and not the fact separate functions are =
needed to use each feature!<br>
In other words, right now one must learn three topics:</p>
<ul>
<li>Forwarding references and reference collapsing;</li>
<li>Rvalue references and move constructors;</li>
<li>Learn about <code>move</code> and <code>forward</code>, when to use the=
m and when <em>not</em> to use them<sup class=3D"footnote-ref"><a id=3D"fnr=
ef1" href=3D"#fn1">1</a></sup>;</li>
</ul>
<p>From the above three, only the first two are <em>fundamental concepts</e=
m> of the language.<br>
The last ones are <em>helper constructs</em>.</p>
</li>
</ul>
<p>With the current proposal focus is left on the fundamental features and =
away from the helper tools. These tools are brought to the absolute minimum=
 <em>both</em> semantically <em>and</em> syntactically.</p>
<ul>
<li><strong>The compiler should be the one writing boilerplate code</strong=
><br>
Considering that, on one hand, there is no decision making on when to use <=
code>move</code> and when <code>forward</code> - this is always predetermin=
ed - and, on the other, the compiler has all the necessary information to d=
o the right choice, there is very little gain of not letting it do the job =
for us.</li>
</ul>
<p>This proposal considers <code>move</code> and <code>forward</code> boile=
rplate (helper tools), which should be streamlined by the compiler as much =
as possible.</p>
<ul>
<li><strong>Higher level abstractions are better, if the lower ones do not =
grant us more possibilities</strong><br>
Lets consider a higher abstraction function in the form of a destructor or =
a <code>dispose()</code> method, against specific implementations in the fo=
rm of some hypothetical <code>image.freeData()</code> or <code>file.close()=
</code>. In almost all, if not all cases the destructor or <code>dispose()<=
/code> is the better interface, because, beyond explicitness, one gains not=
hing from using the specific methods and loses more in the form of less gen=
eric code.</li>
</ul>
<p>This proposal argues the case here is analogous - the use of specific im=
plementations, in the form of <code>forward</code> and <code>move</code>, i=
s inferior to the use of the higher concept of =E2=80=9Cobject passing=E2=
=80=9D.</p>
<ul>
<li><strong>Any good operator for <code>move</code> is also good one for <c=
ode>forward</code></strong><br>
This might look like a cop out, but in reality if a good operator is found =
for one of the functions it will either be also equally useful for the othe=
r, or it will be <em>very</em> hard to come up with similar one for the oth=
er function as well. This goes the opposite direction as well - as long as =
we are not forced to came up with a <em>specific</em> operator, it will be =
easier to actually came up with one.</li>
</ul>
<p>This proposal recognizes strong connection b/w <code>move</code> and <co=
de>forward</code> and considers a single operator the best solution.</p>
<h3 id=3D"motivation-for-use-of-an-operator">Motivation for use of an opera=
tor</h3>
<p>There are multiple good reasons to consider an operator something of hig=
h value:</p>
<ol>
<li>Both <code>move</code> and <code>forward</code> are interfaces to <em>f=
undamental, wildly used</em> language constructs. They should be represente=
d by language-level syntax. Right now, the much less common operation - to =
take the address of an object - has a language level construct, and the muc=
h more commonly used one - to pass an object - does not. There is a strong =
contrast with the fact the entire machinery used by <code>move</code> and <=
code>forward</code> is language based - move ctors, decorators, reference c=
ollapsing - yet there no language construct to use them.</li>
<li>Currently we need to explain that =E2=80=9Cmove does not actually move=
=E2=80=9D and that =E2=80=9Cmove and forward are just a cast=E2=80=9D. This=
 is because <code>move</code> and <code>forward</code> present themselves a=
s a function similar to other <code>std</code> functions like <code>std::co=
py</code> and <code>std::ref</code>, which, like most functions, <em>do</em=
> perform a =E2=80=9Creal work=E2=80=9D. Casts on the other hand are langua=
ge level, <code>constexpr</code> for the most part, actions, performing ess=
entially compiler directives, not =E2=80=9Creal work=E2=80=9D. Operators fi=
t that purpose best.</li>
<li>An operator has the least amount of verbosity, which is welcome for bot=
h <code>move</code> and <code>forward</code> as in both cases the operation=
 is already part of some bigger expression -<br>
<code>func(std::forward&lt;A&gt;(a), std::forward&lt;B&gt;(b))</code>, <cod=
e>_member{std::move(val)}</code>, <code>std::move(val).call()</code>.</li>
</ol>
<h3 id=3D"motivation-against-the-use-of-a-keyword">Motivation against the u=
se of a keyword</h3>
<p>Using a keyword in this particular case will have few disadvantages.</p>
<p>First,  it will not be short and terse enough to be attractive alternati=
ve to the current functions, especially to <code>move</code>.</p>
<p>Second and more importantly, inviting a keyword for both <code>move</cod=
e> and <code>forward</code> will have the unwanted side effect of introduci=
ng a new term, a new category to learn and articulate. Instead of just talk=
ing about =E2=80=9Cforwarding references=E2=80=9D and rvalue references and=
 the syntax to use these, we will have to talk about object <code>give</cod=
e>ing or <code>pass</code>ing as some sort of separate category. Keywords, =
even more so then functions, make things way too =E2=80=9Cofficial=E2=80=9D=
 and declarative, where operators are <em>just syntax</em> - we don=E2=80=
=99t name what we don=E2=80=99t have to name. Where with <code>new</code> a=
nd <code>make_</code> for example naming the action is beneficial, here nam=
ing the action like <code>give</code> or <code>pass</code>  is overly forma=
l and, as said, creates an extra unneeded term.</p>
<p>Last, but not least, introducing a new keyword to C++ has proven to be v=
ery difficult task and the results are filled with compromises.</p>
<h3 id=3D"motivation-against-the-use-of-a-function">Motivation against the =
use of a function</h3>
<p>Core language features should not depend on a library helpers in order t=
o be used.</p>
<p>Rvalue and forwarding references are core language features. They, howev=
er, currently cannot be used (or taught) under core language alone - one ne=
eds to use standard library functions to take advantage of these. This is a=
n unfortunate legacy and something that should not be avoided if <code>forw=
ard</code> and <code>move</code> are to be revisited.</p>
<h3 id=3D"motivation-regarding-stdmove-specifically">Motivation regarding s=
td::move specifically</h3>
<p>The biggest problem with move is its misleading similarity with actual s=
tandard library functions, in particular <code>std::copy</code>. Any outsid=
e observer will be mislead to think both these functions are complimentary =
to one other.<br>
As already mentioned, being so explicit in what the function is doing works=
 to its decrement as <code>move</code> might or might not move in reality, =
in contrast to functions in general.</p>
<h3 id=3D"motivation-regarding-stdforward-specifically">Motivation regardin=
g std::forward specifically</h3>
<p><code>forward</code> is arguably even more problematic and has been alre=
ady a target for debate and previous proposals<sup class=3D"footnote-ref"><=
a id=3D"fnref2" href=3D"#fn2">2</a></sup>.<br>
For completeness I will list the problems again here:</p>
<ul>
<li>Subtle difference with <code>move</code> which leads to uncertainly in =
novice programmers.</li>
<li>The function is used only in one context and that context alone - to pa=
ss-on a =E2=80=9Cforwarding reference=E2=80=9D. This can be seen as quite o=
dd for a function with such a broad name.</li>
<li>Mandatory template argument is unexpected to novice programmers, especi=
ally if they are introduced to <code>move</code> around the same time, whic=
h is it is often the case.  Mandatory explicit template arguments in genera=
l are not common and in some situations are even considered an anti-pattern=
..</li>
<li>The template argument itself can be confusing for what works and what d=
oes not - what are the dos and don=E2=80=99ts. Should/could, for instance, =
decorations be used? Should/could a different type be specified?</li>
<li>For professionals the main issue is the verbosity of both the function =
itself - as it appears in the very verbose context of templates - and, in t=
he case of generic lambda, the template argument itself.  This issue is exp=
lored in detail in P0644<sup class=3D"footnote-ref"><a id=3D"fnref2:1" href=
=3D"#fn2">2</a></sup></li>
</ul>
<h2 id=3D"design-decisions">Design Decisions</h2>
<h3 id=3D"postscript-operator-">Postscript operator &amp;&amp;&gt;</h3>
<p>This proposal considers best solution to all requirements the introducti=
on of a postscript operator <code>&amp;&amp;&gt;</code> with the following =
behavior.</p>
<ul>
<li>If <code>val</code> is lvalue reference, the expression <code>val&amp;&=
amp;&gt;</code> is equivalent to <code>std::move(val)</code>.</li>
<li>In all other cases the expression <code>val&amp;&amp;&gt;</code> is equ=
ivalent to <code>std::forward&lt;decltype(val)&gt;(val)</code>.</li>
</ul>
<p>As a result the variable is either reference-collapsed (=E2=80=9Cforward=
ed=E2=80=9D), or casted to rvalue reference (=E2=80=9Cmoved=E2=80=9D).  Def=
ined this way the operator will correctly cover all current uses of <code>f=
orward</code> and <code>move</code>, including potentially unclear cases, w=
here forwarding should be applied to a variable, which is <em>not</em> a fo=
rwarding reference as defined by the current standard.</p>
<p>As for the syntax, it is specifically chosen to serve a purpose - it is =
visually reminiscent of both rvalue reverences (<code>std::string&amp;&amp;=
</code>) and =E2=80=9Cforwarding references=E2=80=9D <code>T&amp;&amp;</cod=
e>, <code>auto&amp;&amp;</code>. This way there is a strong correlation b/w=
 the decoration of the variable and the action needed to use it.<br>
An angle bracket <code>&gt;</code> is also used, which not only visually si=
gnals movement (moving/forwarding), but more importantly, syntactically dis=
ambiguates against the existing operator &amp;&amp;:<br>
<code>a &amp;&amp; (b || c); //&lt; operator&amp;&amp;(a, operator||(b, c))=
</code><br>
<code>a&amp;&amp;&gt;(b || c); //&lt; std::move(a)(operator||(b, c))</code>=
</p>
<p>The operator being postfix is also of importance because this enables sy=
ntax options, impossible otherwise. For instance it would have been much ha=
rder to use the ampersand <code>&amp;</code> as it is already an existing p=
refix operator.<br>
It also makes the code readable in a natural left to right way:<br>
<code>img&amp;&amp;&gt;.mirrored(); // varibale 'img', convert to rvalue, c=
all mirrored() &amp;&amp;</code><br>
<code>func(arg&amp;&amp;&gt;); // call 'func' with argument 'arg', converte=
d back to "forwarding reference"</code></p>
<h4 id=3D"can-operator--be-a-normal-operator-function">Can operator &amp;&a=
mp;&gt; be a normal operator function?</h4>
<p>No. <code>move</code> can be an operator function, but <code>forward</co=
de> needs a type argument, making it unsuitable.<br>
In the later case, this proposal envisions the compiler supplying the neede=
d template argument =E2=80=9Cbehind the scenes=E2=80=9D.</p>
<h4 id=3D"can-operator--be-implemented-in-terms-of-overloading-or-enable_if=
">Can operator &amp;&amp;&gt; be implemented in terms of overloading or <co=
de>enable_if</code>?</h4>
<p>No. Currently there is no mechanism to tell if an identifier is subject =
of reference collapsing or not.<br>
This distinction is needed so we will be able to differentiate b/w <code>au=
to&amp;&amp;</code>, which might collapse to lvalue reference, and a normal=
 lvalue reference, not a result of a collapse. We =E2=80=9Cmove=E2=80=9D on=
ly normal lvalue references.<br>
This proposal assumes, such a distinction is possible on compiler/preproces=
sor level.</p>
<h4 id=3D"should-operator--be-overloadable.">Should operator &amp;&amp;&gt;=
 be overloadable.</h4>
<p>No. We want it have the predictable behavior in every context, including=
 generic code like templates.</p>
<h3 id=3D"should-stdmove-and-stdforward-be-deprecated">Should std::move and=
 std::forward be deprecated?</h3>
<p>No. This proposal anticipates, <code>move</code> and <code>forward</code=
> to still be used by people who like to be explicit in the syntax, much th=
e same way some people use <code>or</code> and <code>not</code> instead of =
<code>||</code> and <code>!</code>. Also, <code>move</code> and <code>forwa=
rd</code> can be used as teaching tool, to illustrate and explain the proce=
ss of moving and forwarding as well as workings of the proposed operator it=
self. Last, but not least <code>forward</code> can be used to forward an ar=
gument as a different type and <code>move</code> can be used where the user=
 wants to =E2=80=9Cdrop=E2=80=9D reference collapsing and force casting to =
rvalue reference.</p>
<h2 id=3D"previous-work">Previous work</h2>
<p>The author is not aware of previous proposal to merge <code>move</code> =
and <code>forward</code>.<br>
The already mentioned p0644<sup class=3D"footnote-ref"><a id=3D"fnref2:2" h=
ref=3D"#fn2">2</a></sup> deals with the issues regarding <code>forward</cod=
e> and proposes an operator to solve these issues. That proposal was not ac=
cepted, mainly on the grounds of potential confusion to the users<sup class=
=3D"footnote-ref"><a id=3D"fnref3" href=3D"#fn3">3</a></sup>.</p>
<p>Current proposal argues the majority of the issues are alleviated by a p=
ostfix operator, as demonstrated in the previous chapters. The author belie=
ves, not only there is no visual confusion when using the proposed operator=
 &amp;&amp;&gt;, but a strong correlation is build b/w both =E2=80=9Cforwar=
ding references=E2=80=9D and revalue references on one hand, and the syntax=
 to use them on the other.</p>
<h2 id=3D"open-questions">Open Questions</h2>
<ul>
<li>
<p>Should the system have any customization points. The main goal of this i=
s to make it independent of reference collapsing in particular, so that a t=
ype could be forwarded even if it was already processed in some way and not=
 part of a explicit <code>T&amp;&amp;</code>/<code>auto&amp;&amp;</code> ex=
pression.</p>
</li>
<li>
<p>Are we happy with how <code>move</code> and <code>forward</code> work to=
day and should they be used =E2=80=9Cas-is=E2=80=9D in the behind the scene=
 implementations?</p>
</li>
</ul>
<h2 id=3D"acknowledgements">Acknowledgements</h2>
<p>Special thanks to Florian, Ga=C5=A1per A=C5=BEman, Nicol Bolas, Nicolas =
Lesser and other Future Proposals group users for early discussions and cor=
rections<sup class=3D"footnote-ref"><a id=3D"fnref4" href=3D"#fn4">4</a></s=
up>.</p>
<hr class=3D"footnotes-sep">
<section class=3D"footnotes">
<ol class=3D"footnotes-list">
<li class=3D"footnote-item" id=3D"fn1"><p><a href=3D"https://blog.feabhas.c=
om/2018/04/handy-cut-keep-guide-stdforward-stdmove/">guide to std::forward =
and std::move</a>. <a class=3D"footnote-backref" href=3D"#fnref1">=E2=86=A9=
=EF=B8=8E</a></p>
</li>
<li class=3D"footnote-item" id=3D"fn2"><p><a href=3D"http://open-std.org/JT=
C1/SC22/WG21/docs/papers/2017/p0644r1.html">Forward without =E2=80=98forwar=
d=E2=80=99</a>. <a class=3D"footnote-backref" href=3D"#fnref2">=E2=86=A9=EF=
=B8=8E</a> <a class=3D"footnote-backref" href=3D"#fnref2:1">=E2=86=A9=EF=B8=
=8E</a> <a class=3D"footnote-backref" href=3D"#fnref2:2">=E2=86=A9=EF=B8=8E=
</a></p>
</li>
<li class=3D"footnote-item" id=3D"fn3"><p><a href=3D"https://botondballo.wo=
rdpress.com/2017/11/20/trip-report-c-standards-meeting-in-albuquerque-novem=
ber-2017/">Trip Report: november-2017</a> <a class=3D"footnote-backref" hre=
f=3D"#fnref3">=E2=86=A9=EF=B8=8E</a></p>
</li>
<li class=3D"footnote-item" id=3D"fn4"><p><a href=3D"https://groups.google.=
com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ">C++ Future P=
roposals</a> <a class=3D"footnote-backref" href=3D"#fnref4">=E2=86=A9=EF=B8=
=8E</a></p>
</li>
</ol>
</section>
</div>
</body>

</html>

------=_Part_20102_1303376344.1529326874722--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Mon, 18 Jun 2018 17:56:48 +0200
Raw View
--000000000000a9795a056eec9da0
Content-Type: text/plain; charset="UTF-8"

On Mon, 18 Jun 2018 at 15:01, <mihailnajdenov@gmail.com> wrote:

> Updated the proposal with the comments thus far.
>
>
>
> On Thursday, June 7, 2018 at 9:44:56 PM UTC+3, mihailn...@gmail.com wrote:
>>
>> This is continuation of a previous topic
>> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>>
>>
>> Hello, I have written a proposal for merging `forward` and `move` behind
>> a new postscript operator &&>
>>
>> This is the initial draft. Feedback is welcome.
>>
>
FWIW:

1. I agree with all your reasoning, and the proposal in general.
2. The analogy with .dispose() lost me a little bit, but I understand what
you are trying to show - probably because I am already sympathetic to your
general position. This might need rewording.
3. I object to the new *operator* on the grounds that it makes the code
*bizzare-looking* and *cryptic to read*.
4. I very much favour the introduction of a keyword, as I think this will
make intent much clearer when reading code.
5. I understand the community's suspicion of introducing new keywords, but
I think for an important, game-changing language feature such as this, such
fears are overblown and outweighed by the superior readability of a
suitable keyword.



>
>> Thank You
>> MihailNaydenov
>>
> --
> 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/3ecf180f-46c5-49ea-a3f2-ef45226cb23c%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3ecf180f-46c5-49ea-a3f2-ef45226cb23c%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALvx3hbCmoh267bspc4tw_P%3DkrYrXyQgt5tf_x3XfZ5%3DqAmg4w%40mail.gmail.com.

--000000000000a9795a056eec9da0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Mon=
, 18 Jun 2018 at 15:01, &lt;<a href=3D"mailto:mihailnajdenov@gmail.com">mih=
ailnajdenov@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div>Updated the proposal with the comments thus far.</d=
iv><div><br></div><div><br></div><br>On Thursday, June 7, 2018 at 9:44:56 P=
M UTC+3, <a href=3D"mailto:mihailn...@gmail.com" target=3D"_blank">mihailn.=
...@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"><div>This is continuation of a <a href=3D"https://groups.google.com/a/=
isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" rel=3D"nofollow" t=
arget=3D"_blank">previous topic</a>=C2=A0</div><div><br></div><div>Hello, I=
 have written a proposal for merging `forward` and `move` behind a new post=
script operator &amp;&amp;&gt;</div><div><br></div><div>This is the initial=
 draft. Feedback is welcome.</div></div></blockquote></div></blockquote><di=
v><br></div><div>FWIW:</div><div><br></div><div>1. I agree with all your re=
asoning, and the proposal in general.=C2=A0</div><div>2. The analogy with <=
font face=3D"monospace, monospace">.dispose()</font> lost me a little bit, =
but I understand what you are trying to show - probably because I am alread=
y sympathetic to your general position. This might need rewording.</div><di=
v>3. I object to the new <u>operator</u> on the grounds that it makes the c=
ode <i>bizzare-looking</i> and <i>cryptic to read</i>.</div><div>4. I very =
much favour the introduction of a keyword, as I think this will make intent=
 much clearer when reading code.=C2=A0</div><div>5. I understand the commun=
ity&#39;s suspicion of introducing new keywords, but I think for an importa=
nt, game-changing language feature such as this, such fears are overblown a=
nd outweighed by the superior readability of a suitable keyword.</div><div>=
<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<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></div><di=
v>Thank You<br></div><div>MihailNaydenov=C2=A0</div></div></blockquote></di=
v>

<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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/3ecf180f-46c5-49ea-a3f2-ef45226cb23c%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3ecf180f-46c5-=
49ea-a3f2-ef45226cb23c%40isocpp.org</a>.<br>
</blockquote></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/CALvx3hbCmoh267bspc4tw_P%3DkrYrXyQgt5=
tf_x3XfZ5%3DqAmg4w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3hbCmoh2=
67bspc4tw_P%3DkrYrXyQgt5tf_x3XfZ5%3DqAmg4w%40mail.gmail.com</a>.<br />

--000000000000a9795a056eec9da0--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 18 Jun 2018 10:35:26 -0700 (PDT)
Raw View
------=_Part_20733_75228160.1529343326948
Content-Type: multipart/alternative;
 boundary="----=_Part_20734_1972131011.1529343326949"

------=_Part_20734_1972131011.1529343326949
Content-Type: text/plain; charset="UTF-8"

On Monday, June 18, 2018 at 11:57:02 AM UTC-4, Richard Hodges wrote:
>
> On Mon, 18 Jun 2018 at 15:01, <mihailn...@gmail.com <javascript:>> wrote:
>
>> Updated the proposal with the comments thus far.
>>
>>
>>
>> On Thursday, June 7, 2018 at 9:44:56 PM UTC+3, mihailn...@gmail.com
>> wrote:
>>>
>>> This is continuation of a previous topic
>>> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>>>
>>>
>>> Hello, I have written a proposal for merging `forward` and `move` behind
>>> a new postscript operator &&>
>>>
>>> This is the initial draft. Feedback is welcome.
>>>
>>
> FWIW:
>
> 1. I agree with all your reasoning, and the proposal in general.
> 2. The analogy with .dispose() lost me a little bit, but I understand
> what you are trying to show - probably because I am already sympathetic to
> your general position. This might need rewording.
> 3. I object to the new *operator* on the grounds that it makes the code
> *bizzare-looking* and *cryptic to read*.
> 4. I very much favour the introduction of a keyword, as I think this will
> make intent much clearer when reading code.
> 5. I understand the community's suspicion of introducing new keywords, but
> I think for an important, game-changing language feature such as this, such
> fears are overblown and outweighed by the superior readability of a
> suitable keyword.
>

It should be noted that it's not "the community" that is "suspicious of
introducing new keywords"; it's the *committee* that is reluctant. I
imagine if "the community" had its way, C++ would have twice as many
keywords as it currently does, possibly using P0056's prefixing system for
differentiating keywords from identifiers where needed.

--
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/60d5ed99-7ae4-4f96-a27b-5c2396971829%40isocpp.org.

------=_Part_20734_1972131011.1529343326949
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, June 18, 2018 at 11:57:02 AM UTC-4, Richard Hod=
ges 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"><di=
v class=3D"gmail_quote"><div dir=3D"ltr">On Mon, 18 Jun 2018 at 15:01, &lt;=
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"1QEru6fR=
AwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;ret=
urn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">mihai=
ln...@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
 dir=3D"ltr"><div>Updated the proposal with the comments thus far.</div><di=
v><br></div><div><br></div><br>On Thursday, June 7, 2018 at 9:44:56 PM UTC+=
3, <a>mihailn...@gmail.com</a> wrote:<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>This is continuation of a <a href=3D"https://groups=
..google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" rel=
=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D&#39;https://gro=
ups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#3=
9;;return true;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/is=
ocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ&#39;;return true;">pr=
evious topic</a>=C2=A0</div><div><br></div><div>Hello, I have written a pro=
posal for merging `forward` and `move` behind a new postscript operator &am=
p;&amp;&gt;</div><div><br></div><div>This is the initial draft. Feedback is=
 welcome.</div></div></blockquote></div></blockquote><div><br></div><div>FW=
IW:</div><div><br></div><div>1. I agree with all your reasoning, and the pr=
oposal in general.=C2=A0</div><div>2. The analogy with <font face=3D"monosp=
ace, monospace">.dispose()</font> lost me a little bit, but I understand wh=
at you are trying to show - probably because I am already sympathetic to yo=
ur general position. This might need rewording.</div><div>3. I object to th=
e new <u>operator</u> on the grounds that it makes the code <i>bizzare-look=
ing</i> and <i>cryptic to read</i>.</div><div>4. I very much favour the int=
roduction of a keyword, as I think this will make intent much clearer when =
reading code.=C2=A0</div><div>5. I understand the community&#39;s suspicion=
 of introducing new keywords, but I think for an important, game-changing l=
anguage feature such as this, such fears are overblown and outweighed by th=
e superior readability of a suitable keyword.</div></div></div></blockquote=
><div><br></div><div>It should be noted that it&#39;s not &quot;the communi=
ty&quot; that is &quot;suspicious of introducing new keywords&quot;; it&#39=
;s the <i>committee</i> that is reluctant. I imagine if &quot;the community=
&quot; had its way, C++ would have twice as many keywords as it currently d=
oes, possibly using P0056&#39;s prefixing system for differentiating keywor=
ds from identifiers where needed.<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/60d5ed99-7ae4-4f96-a27b-5c2396971829%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/60d5ed99-7ae4-4f96-a27b-5c2396971829=
%40isocpp.org</a>.<br />

------=_Part_20734_1972131011.1529343326949--

------=_Part_20733_75228160.1529343326948--

.


Author: Richard Hodges <hodges.r@gmail.com>
Date: Tue, 19 Jun 2018 09:16:18 +0200
Raw View
--0000000000003ff89f056ef976dd
Content-Type: text/plain; charset="UTF-8"

On Mon, 18 Jun 2018, 19:35 Nicol Bolas, <jmckesson@gmail.com> wrote:

> On Monday, June 18, 2018 at 11:57:02 AM UTC-4, Richard Hodges wrote:
>>
>> On Mon, 18 Jun 2018 at 15:01, <mihailn...@gmail.com> wrote:
>>
>>> Updated the proposal with the comments thus far.
>>>
>>>
>>>
>>> On Thursday, June 7, 2018 at 9:44:56 PM UTC+3, mihailn...@gmail.com
>>> wrote:
>>>>
>>>> This is continuation of a previous topic
>>>> <https://groups.google.com/a/isocpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ>
>>>>
>>>>
>>>> Hello, I have written a proposal for merging `forward` and `move`
>>>> behind a new postscript operator &&>
>>>>
>>>> This is the initial draft. Feedback is welcome.
>>>>
>>>
>> FWIW:
>>
>> 1. I agree with all your reasoning, and the proposal in general.
>> 2. The analogy with .dispose() lost me a little bit, but I understand
>> what you are trying to show - probably because I am already sympathetic to
>> your general position. This might need rewording.
>> 3. I object to the new *operator* on the grounds that it makes the code
>> *bizzare-looking* and *cryptic to read*.
>> 4. I very much favour the introduction of a keyword, as I think this will
>> make intent much clearer when reading code.
>> 5. I understand the community's suspicion of introducing new keywords,
>> but I think for an important, game-changing language feature such as this,
>> such fears are overblown and outweighed by the superior readability of a
>> suitable keyword.
>>
>
> It should be noted that it's not "the community" that is "suspicious of
> introducing new keywords"; it's the *committee* that is reluctant. I
> imagine if "the community" had its way, C++ would have twice as many
> keywords as it currently does, possibly using P0056's prefixing system for
> differentiating keywords from identifiers where needed.
>

Thanks for the correction. If history is a guide, when a committee stands
in the way of a community, bloody revolution is the result.



--
> 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/60d5ed99-7ae4-4f96-a27b-5c2396971829%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/60d5ed99-7ae4-4f96-a27b-5c2396971829%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CALvx3haVaF8UHXBFynZvDGk_3g_GEoRZ5W0SZeWXiYHRzs-W2g%40mail.gmail.com.

--0000000000003ff89f056ef976dd
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Mon, 18 Jun 2018, 19:35 Nicol Bolas, &lt;<a href=3D"mailto:jmckesson@gma=
il.com">jmckesson@gmail.com</a>&gt; wrote:<br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr">On Monday, June 18, 2018 at 11:57:02 AM UTC-4, Ric=
hard Hodges wrote:<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 class=3D"gmail_quote"><div dir=3D"ltr">On Mon, 18 Jun 2018 at 15:01, &=
lt;<a rel=3D"nofollow noreferrer">mihailn...@gmail.com</a>&gt; wrote:<br></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Updated the propos=
al with the comments thus far.</div><div><br></div><div><br></div><br>On Th=
ursday, June 7, 2018 at 9:44:56 PM UTC+3, <a rel=3D"noreferrer">mihailn...@=
gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div>This is continuation of a <a href=3D"https://groups.google.com/a/iso=
cpp.org/d/msg/std-proposals/Kdt1dVwL7bo/wXHhTLpbDQAJ" rel=3D"nofollow noref=
errer" target=3D"_blank">previous topic</a>=C2=A0</div><div><br></div><div>=
Hello, I have written a proposal for merging `forward` and `move` behind a =
new postscript operator &amp;&amp;&gt;</div><div><br></div><div>This is the=
 initial draft. Feedback is welcome.</div></div></blockquote></div></blockq=
uote><div><br></div><div>FWIW:</div><div><br></div><div>1. I agree with all=
 your reasoning, and the proposal in general.=C2=A0</div><div>2. The analog=
y with <font face=3D"monospace, monospace">.dispose()</font> lost me a litt=
le bit, but I understand what you are trying to show - probably because I a=
m already sympathetic to your general position. This might need rewording.<=
/div><div>3. I object to the new <u>operator</u> on the grounds that it mak=
es the code <i>bizzare-looking</i> and <i>cryptic to read</i>.</div><div>4.=
 I very much favour the introduction of a keyword, as I think this will mak=
e intent much clearer when reading code.=C2=A0</div><div>5. I understand th=
e community&#39;s suspicion of introducing new keywords, but I think for an=
 important, game-changing language feature such as this, such fears are ove=
rblown and outweighed by the superior readability of a suitable keyword.</d=
iv></div></div></blockquote><div><br></div><div>It should be noted that it&=
#39;s not &quot;the community&quot; that is &quot;suspicious of introducing=
 new keywords&quot;; it&#39;s the <i>committee</i> that is reluctant. I ima=
gine if &quot;the community&quot; had its way, C++ would have twice as many=
 keywords as it currently does, possibly using P0056&#39;s prefixing system=
 for differentiating keywords from identifiers where needed.<br></div></div=
></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">Tha=
nks for the correction. If history is a guide, when a committee stands in t=
he way of a community, bloody revolution is the result.=C2=A0</div><div dir=
=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div=
><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div dir=3D"ltr"><div></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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/60d5ed99-7ae4-4f96-a27b-5c2396971829%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/60d5ed99-7ae4-4f96-a27b-5c2396971829%40isocpp.org</a>.<br>
</blockquote></div></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/CALvx3haVaF8UHXBFynZvDGk_3g_GEoRZ5W0S=
ZeWXiYHRzs-W2g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALvx3haVaF8UHXBF=
ynZvDGk_3g_GEoRZ5W0SZeWXiYHRzs-W2g%40mail.gmail.com</a>.<br />

--0000000000003ff89f056ef976dd--

.