Topic: Forwarding from containers
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Thu, 05 Feb 2015 19:38:31 -0600
Raw View
The following is a brief sketch of a proposal to simplify forwarding
elements from their containers. It still needs a lot of work to become a
real proposal, but I wanted to run it by folks to see if the general
idea is sane:
Forwarding From Containers
==========================
Currently, forwarding elements from a container is harder than
necessary. While facilities like `std::move` and
`std::make_move_iterator` are helpful for moving, there aren't any
helpers for *forwarding* from a container.
In other words, the following use case, while conceptually simple, is
actually somewhat difficult to implement:
template<typename T>
void do_each(T &&container) {
for(auto &&i : container)
do_once(std::forward<???>(i));
}
I see two (not necessarily mutually-exclusive) solutions to this:
Option 1: `std::forward_if`
---------------------------
One solution for this problem is to allow users to forward an object
based on *another* object's type (i.e. the container type). This gives
us something pretty close to our ideal syntax:
template<typename T>
void do_each(T &&container) {
for(auto &&i : container)
do_once(std::forward_if<T>(i));
}
This is the solution I've chosen in my own work, and the
`std::forward_if` helper is straightforward to implement (although my
implementation may not cover every possibility).
Option 2: Rvalue-aware Containers
---------------------------------
Another option would be to provide rvalue overloads of `begin()` and
`end()` for standard containers. These would have essentially the same
effect as calling `std::make_move_iterator(container.begin())`. However,
the following is insufficient to forward elements:
template<typename T>
void do_each(T &&container) {
for(auto &&i : std::forward<T>(container))
do_once(i); // Will never move!
}
To work around this, you must explicitly forward `i` as well:
template<typename T>
void do_each(T &&container) {
for(auto &&i : std::forward<T>(container))
do_once(std::forward<decltype(i)>(i));
}
In addition to requiring two calls to `std::forward`, the user is
required to get the type of `i` via `decltype`, which makes this code
considerably more verbose than option 1.
Of course, rvalue-aware containers become substantially more useful when
combined with the ranges proposal. With ranges and rvalue-aware
containers, the `std::move` and `std::move_backward` algorithms become
equivalent to:
std::copy(std::move(src), dest);
std::copy_backward(std::move(src), dest);
In addition, many of the other mutating sequence operations become able
to move elements with these additions.
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Scott Prager <splinterofchaos@gmail.com>
Date: Sat, 7 Feb 2015 10:30:21 -0800 (PST)
Raw View
------=_Part_1813_600316942.1423333821491
Content-Type: multipart/alternative;
boundary="----=_Part_1814_648670588.1423333821491"
------=_Part_1814_648670588.1423333821491
Content-Type: text/plain; charset=UTF-8
On Thursday, February 5, 2015 at 8:38:57 PM UTC-5, Jim Porter wrote:
>
> The following is a brief sketch of a proposal to simplify forwarding
> elements from their containers. It still needs a lot of work to become a
> real proposal, but I wanted to run it by folks to see if the general
> idea is sane:
>
>
> Forwarding From Containers
> ==========================
>
> Currently, forwarding elements from a container is harder than
> necessary. While facilities like `std::move` and
> `std::make_move_iterator` are helpful for moving, there aren't any
> helpers for *forwarding* from a container.
>
> In other words, the following use case, while conceptually simple, is
> actually somewhat difficult to implement:
>
> template<typename T>
> void do_each(T &&container) {
> for(auto &&i : container)
> do_once(std::forward<???>(i));
> }
>
Might strengthen the argument by elaborating what should be in the ???
Something like... (untested)
std::conditional_t<std::is_lvalue_referece<T>::value,
std::conditional_t<std::is_const<T>::value, typename T::
const_reference,
typename T::
reference>,
typename T::value_type>
>
> I see two (not necessarily mutually-exclusive) solutions to this:
>
> Option 1: `std::forward_if`
> ---------------------------
>
> One solution for this problem is to allow users to forward an object
> based on *another* object's type (i.e. the container type). This gives
> us something pretty close to our ideal syntax:
>
> template<typename T>
> void do_each(T &&container) {
> for(auto &&i : container)
> do_once(std::forward_if<T>(i));
> }
>
> This is the solution I've chosen in my own work, and the
> `std::forward_if` helper is straightforward to implement (although my
> implementation may not cover every possibility).
>
> Option 2: Rvalue-aware Containers
> ---------------------------------
>
> Another option would be to provide rvalue overloads of `begin()` and
> `end()` for standard containers. These would have essentially the same
> effect as calling `std::make_move_iterator(container.begin())`. However,
> the following is insufficient to forward elements:
>
> template<typename T>
> void do_each(T &&container) {
> for(auto &&i : std::forward<T>(container))
> do_once(i); // Will never move!
> }
>
I believe that for this example to have the intended result,
the standard text of the range-based for loop will have to change.
So, right now, we have... (6.5.4)
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
and *begin-, *and *end-expr* can be different depending on
whether *__range*'s type, *_RangeT* is an array, class, or other.
The text of the three following paragraphs might need to
change, but for example for class type, *begin-* and *end-expr*
will be defined as *__range.begin()* and *__range.end()*, but
should instead be *std::forward<_RangeT>(__range).begin()*
and *std::forward<_RangeT>(__range).end()*.
> To work around this, you must explicitly forward `i` as well:
>
> template<typename T>
> void do_each(T &&container) {
> for(auto &&i : std::forward<T>(container))
> do_once(std::forward<decltype(i)>(i));
> }
>
> In addition to requiring two calls to `std::forward`, the user is
> required to get the type of `i` via `decltype`, which makes this code
> considerably more verbose than option 1.
>
You mention below range-based algorithms; consider *copy_if*.
template<typename C, typename Inserter>
Inserter copy_if(C&& c, Inserter ins) {
return std::copy_if(std::begin(std::forward<C>(c)),
std::end(std::forward<C>(c)),
ins);
}
The *begin* and *end* functions are overloaded on non-const and
const references, but will also need additional overloads for
rvalue-references. (Defined in 24.7.)
>
> Of course, rvalue-aware containers become substantially more useful when
> combined with the ranges proposal. With ranges and rvalue-aware
> containers, the `std::move` and `std::move_backward` algorithms become
> equivalent to:
>
> std::copy(std::move(src), dest);
> std::copy_backward(std::move(src), dest);
>
> In addition, many of the other mutating sequence operations become able
> to move elements with these additions.
>
>
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1814_648670588.1423333821491
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, February 5, 2015 at 8:38:57 PM UTC-5,=
Jim Porter wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The followin=
g is a brief sketch of a proposal to simplify forwarding=20
<br>elements from their containers. It still needs a lot of work to become =
a=20
<br>real proposal, but I wanted to run it by folks to see if the general=20
<br>idea is sane:
<br>
<br>
<br>Forwarding From Containers
<br>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
<br>
<br>Currently, forwarding elements from a container is harder than=20
<br>necessary. While facilities like `std::move` and=20
<br>`std::make_move_iterator` are helpful for moving, there aren't any=20
<br>helpers for *forwarding* from a container.
<br>
<br>In other words, the following use case, while conceptually simple, is=
=20
<br>actually somewhat difficult to implement:
<br>
<br> template<typename T>
<br> void do_each(T &&container) {
<br> for(auto &&i : container)
<br> do_once(std::forward<???>(i))<wbr>;
<br> }
<br></blockquote><div><br></div><div>Might strengthen the argument by elabo=
rating what should be in the ???</div><div><br></div><div>Something like...=
(untested)</div><div><br></div><div class=3D"prettyprint" style=3D"border:=
1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb=
(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><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">conditional_t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">is_lvalue_referece</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">T</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">>::</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">value</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</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">conditional_t</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">is_const</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #00=
0;" 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">value</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">typ=
ename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">const_reference</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> <br> =
&nbs=
p; &n=
bsp; </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">reference</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">>,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br> &nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">value_type<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">></span>=
</div></code></div><div></div><div> </div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">
<br>I see two (not necessarily mutually-exclusive) solutions to this:
<br>
<br>Option 1: `std::forward_if`
<br>---------------------------
<br>
<br>One solution for this problem is to allow users to forward an object=20
<br>based on *another* object's type (i.e. the container type). This gives=
=20
<br>us something pretty close to our ideal syntax:
<br>
<br> template<typename T>
<br> void do_each(T &&container) {
<br> for(auto &&i : container)
<br> do_once(std::forward_if<T>(i)<wbr>);
<br> }
<br>
<br>This is the solution I've chosen in my own work, and the=20
<br>`std::forward_if` helper is straightforward to implement (although my=
=20
<br>implementation may not cover every possibility).
<br>
<br>Option 2: Rvalue-aware Containers
<br>------------------------------<wbr>---
<br>
<br>Another option would be to provide rvalue overloads of `begin()` and=20
<br>`end()` for standard containers. These would have essentially the same=
=20
<br>effect as calling `std::make_move_iterator(<wbr>container.begin())`. Ho=
wever,=20
<br>the following is insufficient to forward elements:
<br>
<br> template<typename T>
<br> void do_each(T &&container) {
<br> for(auto &&i : std::forward<T>(contai=
ner))
<br> do_once(i); // Will never move!
<br> }
<br></blockquote><div><br></div><div>I believe that for this example to hav=
e the intended result,</div><div>the standard text of the range-based for l=
oop will have to change.</div><div><br></div><div>So, right now, we have...=
(6.5.4)</div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187=
, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&&</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> __range </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> range</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">-</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ini=
t</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">for</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: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> __begin </span><span style=3D"color: #660;" class=3D"sty=
led-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"=
>begin</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">expr</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> __e=
nd </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">end</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">-</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">expr</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br> __begin </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">!=3D</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> __end</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"styled-by-prettify">__begin </span><span style=3D"color: #66=
0;" 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> </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">for</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">-</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ra=
nge</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">declaration </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: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">__begin</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br> statement<br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></code></div><=
div><br></div><div>and <i>begin-, </i>and <i>end-expr</i> can be diffe=
rent depending on</div><div>whether <i>__range</i>'s type, <i>_RangeT</i>&n=
bsp;is an array, class, or other.</div><div>The text of the three following=
paragraphs might need to</div><div>change, but for example for class type,=
<i>begin-</i> and <i>end-expr</i></div><div>will be defined as <i>__r=
ange.begin()</i> and <i>__range.end()</i>, but</div><div>should instea=
d be <i>std::forward<_RangeT>(__range).begin()</i></div><div>and <i>s=
td::forward<_RangeT>(__range).end()</i>.</div><div><br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">
<br>To work around this, you must explicitly forward `i` as well:
<br>
<br> template<typename T>
<br> void do_each(T &&container) {
<br> for(auto &&i : std::forward<T>(contai=
ner))
<br> do_once(std::forward<<wbr>decltype(i)>=
(i));
<br> }
<br>
<br>In addition to requiring two calls to `std::forward`, the user is=20
<br>required to get the type of `i` via `decltype`, which makes this code=
=20
<br>considerably more verbose than option 1.
<br></blockquote><div><br></div><div>You mention below range-based algorith=
ms; consider <i>copy_if</i>.<br></div><div><br></div><div class=3D"pre=
ttyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-w=
ord; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><di=
v class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">typename</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"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">typename</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Inserter</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: #606;" class=
=3D"styled-by-prettify">Inserter</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> copy_if</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">C</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&&</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> c</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: #606;" class=3D"styled-by-prettify">Inserter</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> ins</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> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">copy_if</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">begin</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">forward</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">C</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)),</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br> &nb=
sp; std</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">end</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">forward</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">C</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)),</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br> &nb=
sp; ins</spa=
n><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></div></code></div><=
div><br></div><div>The <i>begin</i> and <i>end</i> functions are =
overloaded on non-const and </div><div>const references, but will also=
need additional overloads for</div><div>rvalue-references. (Defined in 24.=
7.)</div><div> </div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>Of course, rvalue-aware containers become substantially more useful whe=
n=20
<br>combined with the ranges proposal. With ranges and rvalue-aware=20
<br>containers, the `std::move` and `std::move_backward` algorithms become=
=20
<br>equivalent to:
<br>
<br> std::copy(std::move(src), dest);
<br> std::copy_backward(std::move(<wbr>src), dest);
<br>
<br>In addition, many of the other mutating sequence operations become able=
=20
<br>to move elements with these additions.
<br>
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1814_648670588.1423333821491--
------=_Part_1813_600316942.1423333821491--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sun, 8 Feb 2015 22:00:38 -0800 (PST)
Raw View
------=_Part_2077_1698246212.1423461638859
Content-Type: multipart/alternative;
boundary="----=_Part_2078_218932807.1423461638860"
------=_Part_2078_218932807.1423461638860
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, February 5, 2015 at 5:38:57 PM UTC-8, Jim Porter wrote:
>
> The following is a brief sketch of a proposal to simplify forwarding=20
> elements from their containers. It still needs a lot of work to become a=
=20
> real proposal, but I wanted to run it by folks to see if the general=20
> idea is sane:=20
>
[...]
> Option 1: `std::forward_if`=20
> ---------------------------=20
>
> One solution for this problem is to allow users to forward an object=20
> based on *another* object's type (i.e. the container type). This gives=20
> us something pretty close to our ideal syntax:=20
>
> template<typename T>=20
> void do_each(T &&container) {=20
> for(auto &&i : container)=20
> do_once(std::forward_if<T>(i));=20
> }=20
>
> This is the solution I've chosen in my own work, and the=20
> `std::forward_if` helper is straightforward to implement (although my=20
> implementation may not cover every possibility).=20
>
This seems like a great idea to me!
Please post your implementation of forward_if, especially if it's=20
significantly different from this one.
#include <type_traits>
template <class T>
struct forward_if_wrapper {
template <class U, class Enable =3D std::enable_if_t<(sizeof(std::
remove_reference<U>), std::is_reference<T>::value)>>
static U forward(U&& u) {
return u;
}
template <class U, class Enable =3D std::enable_if_t<(sizeof(std::
remove_reference<U>), !std::is_reference<T>::value)>>
static decltype(auto) forward(U&& u) {
return static_cast<typename std::remove_reference<U>::type &&>(u);
}
};
auto forward =3D [](auto&& t) -> decltype(auto) { return forward_if_wrapper=
<
decltype(t)>::forward(t); };
template <class T> auto forward_if =3D [](auto&& u) -> decltype(auto) { ret=
urn=20
forward_if_wrapper<T>::forward(u); };
// --------
#include <stdio.h>
#include <vector>
template<class Elt>
void bar(Elt&&) {
printf("Called %s\n", __PRETTY_FUNCTION__);
}
template<class Container>
void foo(Container&& c) {
for (auto&& elt : c) {
bar(forward_if_wrapper<Container>::forward(elt));
}
}
int main() {
std::vector<int> v =3D {1,2};
foo(v);
foo(std::move(v));
}
In fact, I would ask: Is there really any use-case for the existing=20
std::forward<T> that would break if we replaced std::forward<T>(t) with=20
std::forward_if<T>(t)? Could we just make std::forward in C++1z behave like=
=20
the std::forward_if above, so that one library function will suffice for=20
both purposes?
my $.02,
=E2=80=93Arthur
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2078_218932807.1423461638860
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, February 5, 2015 at 5:38:57 PM UTC-8, Jim Por=
ter wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">The following is a b=
rief sketch of a proposal to simplify forwarding=20
<br>elements from their containers. It still needs a lot of work to become =
a=20
<br>real proposal, but I wanted to run it by folks to see if the general=20
<br>idea is sane:
<br></blockquote><div>[...]</div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;">Option 1: `std::forward_if`
<br>---------------------------
<br>
<br>One solution for this problem is to allow users to forward an object=20
<br>based on *another* object's type (i.e. the container type). This gives=
=20
<br>us something pretty close to our ideal syntax:
<br>
<br> template<typename T>
<br> void do_each(T &&container) {
<br> for(auto &&i : container)
<br> do_once(std::forward_if<T>(i)<wbr>);
<br> }
<br>
<br>This is the solution I've chosen in my own work, and the=20
<br>`std::forward_if` helper is straightforward to implement (although my=
=20
<br>implementation may not cover every possibility).
<br></blockquote><div><br></div><div>This seems like a great idea to me!</d=
iv><div>Please post your implementation of <font face=3D"courier new, monos=
pace">forward_if</font>, especially if it's significantly different from th=
is one.</div><div><br></div><div><div><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify"><type_traits></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">template</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=
"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> forward_if_wrapper </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-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><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</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"> U</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: #008;" class=3D"styled-by-prettify">class</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Enable</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">enable_if_t</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify"><(</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>sizeof</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">remove_reference</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">U</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">>),</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">is_reference</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</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">>::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">value</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-pre=
ttify">static</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><font color=3D"#000088"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">U</span></font><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> forward</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">U</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
;&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</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> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> u</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> </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 st=
yle=3D"color: #008;" class=3D"styled-by-prettify">template</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: #00=
8;" class=3D"styled-by-prettify">class</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> U</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"styled-by-prettify=
">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Enable</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=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"styled-by-prettify">enable_if_t</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify"><(</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">rem=
ove_reference</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">U</=
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">std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">is_reference</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify"><</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=
-prettify">value</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)>></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br> </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">static</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><font color=3D"#000088"><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: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</span></font><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> forward</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">U</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&&</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> u</span><spa=
n 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> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static_cast</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">remove_reference</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">U</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">>::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">type </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&&>(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">u</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &=
nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> forward </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"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">[](</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">auto</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 style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">-></span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </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=
: #008;" class=3D"styled-by-prettify">auto</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"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> forwar=
d_if_wrapper</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">decl=
type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">t</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)>::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">forward</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 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-b=
y-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">te=
mplate</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span s=
tyle=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: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> forward_if </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</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: #008;" class=3D"styled-by-prettif=
y">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&am=
p;&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">-></span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </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"styled-by-prettify">return</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> forward_if_wrapper</s=
pan><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">>::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">forward</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">u</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
--------</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">#inc=
lude</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify"><stdio.h>=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #080;" class=3D"styled-by-prettify"><vector></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">template</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Elt</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Elt</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&&)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </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> printf</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #080;" class=3D"styled-by-prettify">"Called %s\n"</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> __PRETTY_FUNCTION__</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></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><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Container</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><span style=3D"color: #008;" class=3D"styled-by-prettify">void</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Container</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"colo=
r: #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-b=
y-prettify"><br> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">for</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: #008;" class=3D"styled-by-prettify">auto<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&&<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> elt </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> bar</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">forward_if_wrapper</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Container</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>::</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">forward</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">elt</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: #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">}</sp=
an><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"> main</span><span style=
=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> std</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">vector</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify"><int></span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> v </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><sp=
an style=3D"color: #660;" 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-prettify"><br> foo</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">v</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br> foo</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">move</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">v</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><div><b=
r></div></div></div><div><br></div><div>In fact, I would ask: Is there real=
ly any use-case for the existing <font face=3D"courier new, monospace">std:=
:forward<T></font> that would break if we replaced <font face=3D"cour=
ier new, monospace">std::forward<T>(t)</font> with <font face=3D"cour=
ier new, monospace">std::forward_if<T>(t)</font>? Could we just make =
<font face=3D"courier new, monospace">std::forward</font> in C++1z behave l=
ike the <font face=3D"courier new, monospace">std::forward_if</font> above,=
so that one library function will suffice for both purposes?</div><div><br=
></div><div>my $.02,</div><div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2078_218932807.1423461638860--
------=_Part_2077_1698246212.1423461638859--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sun, 8 Feb 2015 22:11:21 -0800 (PST)
Raw View
------=_Part_2009_346244987.1423462281965
Content-Type: multipart/alternative;
boundary="----=_Part_2010_1806296786.1423462281966"
------=_Part_2010_1806296786.1423462281966
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, February 8, 2015 at 10:00:39 PM UTC-8, Arthur O'Dwyer wrote:
[...]=20
> This seems like a great idea to me!
> Please post your implementation of forward_if, especially if it's=20
> significantly different from this one.
>
[...]=20
> template<class Container>
> void foo(Container&& c) {
> for (auto&& elt : c) {
> bar(forward_if_wrapper<Container>::forward(elt));
> }
> }
>
Oops; that code changed in between when I copied it and when I pasted it.=
=20
I've put the real code on StackOverflow, here:
http://stackoverflow.com/a/28403749/1424877
In fact, I would ask: Is there really any use-case for the existing=20
> std::forward<T> that would break if we replaced std::forward<T>(t) with=
=20
> std::forward_if<T>(t)? Could we just make std::forward in C++1z behave=20
> like the std::forward_if above, so that one library function will suffice=
=20
> for both purposes?
>
=E2=80=93Arthur=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2010_1806296786.1423462281966
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, February 8, 2015 at 10:00:39 PM UTC-8, Arthur O=
'Dwyer wrote:<div>[...] </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>This seems like a great idea to me!</div><div>P=
lease post your implementation of <font face=3D"courier new, monospace">for=
ward_if</font>, especially if it's significantly different from this one.</=
div></div></blockquote><div>[...] </div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div></div><div><div><div style=3D"backgrou=
nd-color:rgb(250,250,250);border:1px solid rgb(187,187,187);word-wrap:break=
-word"><code><div><span style=3D"color:#008">template</span><span style=3D"=
color:#660"><</span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> </span><span style=3D"color:#606">Container</span><span st=
yle=3D"color:#660">></span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">void</span><span style=3D"color:#000"> foo</span><span =
style=3D"color:#660">(</span><span style=3D"color:#606">Container</span><sp=
an style=3D"color:#660">&&</span><span style=3D"color:#000"> c</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><span style=3D"color:#008">for</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">(</span><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#660">&&</span><span style=3D"color:#000">=
elt </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"> </sp=
an><span style=3D"color:#660">{</span><span style=3D"color:#000"><br> =
bar</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#000">forward_if_wrapper</span><span style=3D"color:#660"><=
</span><span style=3D"color:#606">Contain<wbr>er</span><span style=3D"color=
:#660">>::</span><span style=3D"color:#000">forward</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">elt</span><span style=3D"co=
lor:#660">));</span><span style=3D"color:#000"><br> </span><sp=
an 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></div></div></div></blockquote><div><br></div><div>Oops; that c=
ode changed in between when I copied it and when I pasted it. I've put the =
real code on StackOverflow, here:</div><div>http://stackoverflow.com/a/2840=
3749/1424877</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>In fact, I would ask: Is there really any use-case=
for the existing <font face=3D"courier new, monospace">std::forward<T&g=
t;</font> that would break if we replaced <font face=3D"courier new, monosp=
ace">std::forward<T>(t)</font> with <font face=3D"courier new, monosp=
ace">std::forward_if<T>(t)</font>? Could we just make <font face=3D"c=
ourier new, monospace">std::forward</font> in C++1z behave like the <font f=
ace=3D"courier new, monospace">std::forward_if</font> above, so that one li=
brary function will suffice for both purposes?</div></div></blockquote><div=
><br></div><div>=E2=80=93Arthur </div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2010_1806296786.1423462281966--
------=_Part_2009_346244987.1423462281965--
.
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Mon, 09 Feb 2015 00:17:59 -0600
Raw View
On 2/7/2015 12:30 PM, Scott Prager wrote:
> On Thursday, February 5, 2015 at 8:38:57 PM UTC-5, Jim Porter wrote:
> In other words, the following use case, while conceptually simple, is
> actually somewhat difficult to implement:
>
> template<typename T>
> void do_each(T &&container) {
> for(auto &&i : container)
> do_once(std::forward<???>(i));
> }
>
>
> Might strengthen the argument by elaborating what should be in the ???
Unfortunately, I think it was lost in one of my edits, but this was just
intended to be an idealized example, and then the rest of the paper
would be about figuring out what "???" should be.
As you mentioned below, there are other areas I should probably
elaborate on, like how std::begin()/end() should be made rvalue-aware
for option (2). I'll try to write up some more details for that.
- Jim
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Mon, 09 Feb 2015 00:20:35 -0600
Raw View
On 2/9/2015 12:00 AM, Arthur O'Dwyer wrote:
> This seems like a great idea to me!
> Please post your implementation of forward_if, especially if it's
> significantly different from this one.
Here's my implementation (which has unit tests, but there's always the
chance I got something wrong, since RVO can hide bugs here):
template<typename Container, typename Element>
inline decltype(auto) move_if(Element &&value) {
using Value = typename std::remove_reference<Element>::type;
using ReturnType = typename std::conditional<
std::is_lvalue_reference<Container>::value, Value &, Value &&
>::type;
return static_cast<ReturnType>(value);
}
That requires C++14, obviously, for the `decltype(auto)`.
> In fact, I would ask: Is there really any use-case for the existing
> std::forward<T> that would break if we replaced std::forward<T>(t) with
> std::forward_if<T>(t)? Could we just make std::forward in C++1z behave
> like the std::forward_if above, so that one library function will
> suffice for both purposes?
That should work, yes. I can see an argument that std::forward should
remain as-is to prevent people from accidentally using the wrong type in
the template, but that might not be a major concern in reality.
- Jim
--
---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 9 Feb 2015 14:38:26 +0800
Raw View
--Apple-Mail=_EBDA0A27-BD38-4183-9C1B-03CF2662DB19
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9302=E2=80=9306, at 9:38 AM, Jim Porter <jvp4846@g.rit.edu>=
wrote:
>=20
> To work around this, you must explicitly forward `i` as well:
I can=E2=80=99t imagine how a class providing rvalue begin() and end() woul=
d want the lvalue overloads called in such a context. (Well, at least not i=
f begin() returns an ordinary move iterator.) Has an adjustment to the defi=
nition of range-for, as Scott suggested, already been proposed?
The problem with forward_if is that the client needs to know whether the ge=
neric source object owns the returned value, which is isn=E2=80=99t very ge=
neric. It won=E2=80=99t work with views. The utility works well enough for =
now, but such style isn=E2=80=99t a good language/library design direction.
There was some in-depth discussion on this list last year. Check for EWG is=
sues.
Another problem with rvalue containers is that rvalues are often temporarie=
s, so there=E2=80=99s a large intersection of rvalue begin() with defective=
use-cases that produce dangling references. See also my paper N4221 =E2=80=
=9CGeneralized lifetime extension,=E2=80=9D which is currently getting a re=
vision. (Latest draft: http://bit.ly/genlife .)
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_EBDA0A27-BD38-4183-9C1B-03CF2662DB19
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9306, at 9:38 AM, Jim Porter <<a href=3D"mailto:jvp4846@g.rit.edu=
" class=3D"">jvp4846@g.rit.edu</a>> wrote:</div><br class=3D"Apple-inter=
change-newline"><div class=3D""><span style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant: normal; font-weight: normal;=
letter-spacing: normal; line-height: normal; orphans: auto; text-align: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; displa=
y: inline !important;" class=3D"">To work around this, you must explicitly =
forward `i` as well:</span></div></blockquote></div><div class=3D""><br cla=
ss=3D""></div><div class=3D"">I can=E2=80=99t imagine how a class providing=
rvalue <font face=3D"Courier" class=3D"">begin()</font> and <font face=3D"=
Courier" class=3D"">end()</font> would want the lvalue overloads called in =
such a context. (Well, at least not if <font face=3D"Courier" class=3D"">be=
gin()</font> returns an ordinary move iterator.) Has an adjustment to the d=
efinition of range-for, as Scott suggested, already been proposed?</div><di=
v class=3D""><br class=3D""></div><div class=3D"">The problem with <font fa=
ce=3D"Courier" class=3D"">forward_if</font> is that the client needs to kno=
w whether the generic source object owns the returned value, which is isn=
=E2=80=99t very generic. It won=E2=80=99t work with views. The utility work=
s well enough for now, but such style isn=E2=80=99t a good language/library=
design direction.</div><div class=3D""><br class=3D""></div><div class=3D"=
">There was some in-depth discussion on this list last year. Check for EWG =
issues.</div><div class=3D""><br class=3D""></div><div class=3D"">Another p=
roblem with rvalue containers is that rvalues are often temporaries, so the=
re=E2=80=99s a large intersection of rvalue <font face=3D"Courier" class=3D=
"">begin()</font> with defective use-cases that produce dangling references=
.. See also my paper N4221 =E2=80=9CGeneralized lifetime extension,=E2=80=9D=
which is currently getting a revision. (Latest draft: <a href=3D"http=
://bit.ly/genlife" class=3D"">http://bit.ly/genlife</a> .)</div></body></ht=
ml>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_EBDA0A27-BD38-4183-9C1B-03CF2662DB19--
.
Author: Jim Porter <jvp4846@g.rit.edu>
Date: Mon, 09 Feb 2015 02:44:10 -0600
Raw View
On 2/9/2015 12:38 AM, David Krauss wrote:
>
>> On 2015=E2=80=9302=E2=80=9306, at 9:38 AM, Jim Porter <jvp4846@g.rit.edu
>> <mailto:jvp4846@g.rit.edu>> wrote:
>>
>> To work around this, you must explicitly forward `i` as well:
>
> I can=E2=80=99t imagine how a class providing rvalue begin() and end() wo=
uld
> want the lvalue overloads called in such a context. (Well, at least not
> if begin() returns an ordinary move iterator.) Has an adjustment to the
> definition of range-for, as Scott suggested, already been proposed?
That's something I'd need to address in the actual proposal. One=20
difficulty is that I think range-for over an ordinary move iterator pair=20
would just move the value to the for-range-declaration, and so you'd=20
still have to find a way to generically forward that value to your=20
destination. I haven't tried to make a proof-of-concept for this part=20
yet, however.
> The problem with forward_if is that the client needs to know whether the
> generic source object owns the returned value, which is isn=E2=80=99t ver=
y
> generic. It won=E2=80=99t work with views. The utility works well enough =
for
> now, but such style isn=E2=80=99t a good language/library design directio=
n.
Doesn't the <algorithm> form of std::move/std::move_if have the same=20
problem with views? If not, how does it solve the problem? (I suppose=20
moving is a bit different from forwarding, but I don't know if that=20
difference matters here.)
> There was some in-depth discussion on this list last year. Check for EWG
> issues.
I couldn't find any EWG issues; the closest I found is this proposal,=20
but it seems to be about much more than forwarding from containers:=20
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3686.html>.
- Jim
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 9 Feb 2015 19:15:20 +0800
Raw View
--Apple-Mail=_24550938-1377-4E12-BACF-075313767027
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9302=E2=80=9309, at 4:44 PM, Jim Porter <jvp4846@g.rit.edu>=
wrote:
>=20
> On 2/9/2015 12:38 AM, David Krauss wrote:
>>=20
>>> On 2015=E2=80=9302=E2=80=9306, at 9:38 AM, Jim Porter <jvp4846@g.rit.ed=
u
>>> <mailto:jvp4846@g.rit.edu>> wrote:
>>>=20
>>> To work around this, you must explicitly forward `i` as well:
>>=20
>> I can=E2=80=99t imagine how a class providing rvalue begin() and end() w=
ould
>> want the lvalue overloads called in such a context. (Well, at least not
>> if begin() returns an ordinary move iterator.) Has an adjustment to the
>> definition of range-for, as Scott suggested, already been proposed?
Ah=E2=80=A6 brain fart. You can=E2=80=99t just substitute a move iterator f=
or an ordinary iterator because a move iterator can only safely be derefere=
nced once. For example, if you tried use such a range-for to populate two o=
ther sequences, you=E2=80=99d be moving each object twice.
I don=E2=80=99t think this is something that range-for will ever achieve. A=
nd, we might want a new kind of =E2=80=9Cforwarding iterator=E2=80=9D in ad=
dition to move_iterator.
It would be nice if there could be an operator * () && overload. But, then =
iterator arithmetic would inadvertently signal moves. And you can=E2=80=99t=
add a member function to all iterators. I guess the next best option is to=
define std::iter_forward to dispatch to a member function that forwarding =
iterators must implement, and otherwise just to do a plain dereference.
> That's something I'd need to address in the actual proposal. One difficul=
ty is that I think range-for over an ordinary move iterator pair would just=
move the value to the for-range-declaration, and so you'd still have to fi=
nd a way to generically forward that value to your destination.
The for-range-declaration is a forwarding reference, nothing really gets mo=
ved to it. The question is how the iterators should do forwarding onward fr=
om that reference.
> I haven't tried to make a proof-of-concept for this part yet, however.
Yep, the only way to find out for sure is to try and see.
>> The problem with forward_if is that the client needs to know whether the
>> generic source object owns the returned value, which is isn=E2=80=99t ve=
ry
>> generic. It won=E2=80=99t work with views. The utility works well enough=
for
>> now, but such style isn=E2=80=99t a good language/library design directi=
on.
>=20
> Doesn't the <algorithm> form of std::move/std::move_if have the same prob=
lem with views? If not, how does it solve the problem? (I suppose moving is=
a bit different from forwarding, but I don't know if that difference matte=
rs here.)
Exactly. You can only move when you know beforehand that you have permissio=
n to do so. The problem at hand is to determine ownership, given something =
that might be a container, or just keeping a pair of member iterators.
>> There was some in-depth discussion on this list last year. Check for EWG
>> issues.
>=20
> I couldn't find any EWG issues; the closest I found is this proposal, but=
it seems to be about much more than forwarding from containers: <http://ww=
w.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3686.html>.
Yeah, that looks like a chunk of a Ranges TS draft. In particular, the last=
paragraph of "The Traversable template argument=E2=80=9D is significant. T=
hat document has certainly been superseded by now, but perhaps an iterator =
spec can be back-ported from ranges.
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_24550938-1377-4E12-BACF-075313767027
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9302=
=E2=80=9309, at 4:44 PM, Jim Porter <<a href=3D"mailto:jvp4846@g.rit.edu=
" class=3D"">jvp4846@g.rit.edu</a>> wrote:</div><br class=3D"Apple-inter=
change-newline"><div class=3D"">On 2/9/2015 12:38 AM, David Krauss wrote:<b=
r class=3D""><blockquote type=3D"cite" class=3D""><br class=3D""><blockquot=
e type=3D"cite" class=3D"">On 2015=E2=80=9302=E2=80=9306, at 9:38 AM, Jim P=
orter <<a href=3D"mailto:jvp4846@g.rit.edu" class=3D"">jvp4846@g.rit.edu=
</a><br class=3D""><<a href=3D"mailto:jvp4846@g.rit.edu" class=3D"">mail=
to:jvp4846@g.rit.edu</a>>> wrote:<br class=3D""><br class=3D"">To wor=
k around this, you must explicitly forward `i` as well:<br class=3D""></blo=
ckquote><br class=3D"">I can=E2=80=99t imagine how a class providing rvalue=
begin() and end() would<br class=3D"">want the lvalue overloads called in =
such a context. (Well, at least not<br class=3D"">if begin() returns an ord=
inary move iterator.) Has an adjustment to the<br class=3D"">definition of =
range-for, as Scott suggested, already been proposed?</blockquote></div></b=
lockquote><div><br class=3D""></div><div>Ah=E2=80=A6 brain fart. You can=E2=
=80=99t just substitute a move iterator for an ordinary iterator because a =
move iterator can only safely be dereferenced once. For example, if you tri=
ed use such a range-for to populate two other sequences, you=E2=80=99d be m=
oving each object twice.</div><div><br class=3D""></div><div>I don=E2=80=99=
t think this is something that range-for will ever achieve. And, we might w=
ant a new kind of =E2=80=9Cforwarding iterator=E2=80=9D in addition to <fon=
t face=3D"Courier" class=3D"">move_iterator</font>.</div><div><br class=3D"=
"></div><div>It would be nice if there could be an <font face=3D"Couri=
er" class=3D"">operator * () &&</font> overload. But, then iterator=
arithmetic would inadvertently signal moves. And you can=E2=80=99t add a m=
ember function to all iterators. I guess the next best option is to define =
<font face=3D"Courier" class=3D"">std::iter_forward</font> to dispatch to a=
member function that forwarding iterators must implement, and otherwise ju=
st to do a plain dereference.</div><div><br class=3D""></div><blockquote ty=
pe=3D"cite" class=3D""></blockquote><blockquote type=3D"cite" class=3D""><d=
iv class=3D"">That's something I'd need to address in the actual proposal. =
One difficulty is that I think range-for over an ordinary move iterator pai=
r would just move the value to the for-range-declaration, and so you'd stil=
l have to find a way to generically forward that value to your destination.=
</div></blockquote><div><br class=3D""></div><div>The for-range-declaration=
is a forwarding reference, nothing really gets moved to it. The question i=
s how the iterators should do forwarding onward from that reference.</div><=
br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D""> I haven=
't tried to make a proof-of-concept for this part yet, however.<br class=3D=
""></div></blockquote><div><br class=3D""></div>Yep, the only way to find o=
ut for sure is to try and see.<br class=3D""><div><br class=3D""></div><blo=
ckquote type=3D"cite" class=3D""><div class=3D""><blockquote type=3D"cite" =
class=3D"">The problem with forward_if is that the client needs to know whe=
ther the<br class=3D"">generic source object owns the returned value, which=
is isn=E2=80=99t very<br class=3D"">generic. It won=E2=80=99t work with vi=
ews. The utility works well enough for<br class=3D"">now, but such style is=
n=E2=80=99t a good language/library design direction.<br class=3D""></block=
quote><br class=3D"">Doesn't the <algorithm> form of std::move/std::m=
ove_if have the same problem with views? If not, how does it solve the prob=
lem? (I suppose moving is a bit different from forwarding, but I don't know=
if that difference matters here.)<br class=3D""></div></blockquote><div><b=
r class=3D""></div><div>Exactly. You can only move when you know beforehand=
that you have permission to do so. The problem at hand is to determine own=
ership, given something that might be a container, or just keeping a pair o=
f member iterators.</div><div><br class=3D""></div><blockquote type=3D"cite=
" class=3D""><div class=3D""><blockquote type=3D"cite" class=3D"">There was=
some in-depth discussion on this list last year. Check for EWG<br class=3D=
"">issues.<br class=3D""></blockquote><br class=3D"">I couldn't find any EW=
G issues; the closest I found is this proposal, but it seems to be about mu=
ch more than forwarding from containers: <<a href=3D"http://www.open-std=
..org/jtc1/sc22/wg21/docs/papers/2013/n3686.html" class=3D"">http://www.open=
-std.org/jtc1/sc22/wg21/docs/papers/2013/n3686.html</a>>.<br class=3D"">=
</div></blockquote><div><br class=3D""></div><div>Yeah, that looks like a c=
hunk of a Ranges TS draft. In particular, the last paragraph of "The T=
raversable template argument=E2=80=9D is significant. That document ha=
s certainly been superseded by now, but perhaps an iterator spec can be bac=
k-ported from ranges.</div></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_24550938-1377-4E12-BACF-075313767027--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Mon, 9 Feb 2015 10:33:16 -0800 (PST)
Raw View
------=_Part_2532_347673883.1423506796035
Content-Type: multipart/alternative;
boundary="----=_Part_2533_51948094.1423506796035"
------=_Part_2533_51948094.1423506796035
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, February 8, 2015 at 10:25:12 PM UTC-8, Jim Porter wrote:
>
> On 2/9/2015 12:00 AM, Arthur O'Dwyer wrote:=20
> > This seems like a great idea to me!=20
> > Please post your implementation of forward_if, especially if it's=20
> > significantly different from this one.=20
>
> Here's my implementation (which has unit tests, but there's always the=20
> chance I got something wrong, since RVO can hide bugs here):=20
>
> template<typename Container, typename Element>=20
> inline decltype(auto) move_if(Element &&value) {=20
> using Value =3D typename std::remove_reference<Element>::type;=20
> using ReturnType =3D typename std::conditional<=20
> std::is_lvalue_reference<Container>::value, Value &, Value &&=20
> >::type;=20
> return static_cast<ReturnType>(value);=20
> }
>
I just wanted to say: wow! That is WAY less code (and more readable, and=20
more likely to be optimized) than my SFINAE version. Hooray for=20
decltype(auto) and std::conditional!
(Btw, I think you're unnecessarily worried about RVO; I can't think of any=
=20
"bug" it might hide, here *or* in general.)
> In fact, I would ask: Is there really any use-case for the existing=20
> > std::forward<T> that would break if we replaced std::forward<T>(t) with=
=20
> > std::forward_if<T>(t)? Could we just make std::forward in C++1z behave=
=20
> > like the std::forward_if above, so that one library function will=20
> > suffice for both purposes?=20
>
> That should work, yes. I can see an argument that std::forward should=20
> remain as-is to prevent people from accidentally using the wrong type in=
=20
> the template, but that might not be a major concern in reality.=20
>
The standard language (N4296) says:
template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexce=
pt;
template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcep=
t;
Returns: static_cast<T&&>(t).
=20
Remark: If the second form is instantiated with an lvalue reference type,=
=20
the program is ill-formed.
The remark forbids constructs such as std::forward<T>(std::move(t)) (when =
T&&=20
t was passed an lvalue) and std::forward<int&>(42). Neither of these seem=
=20
like common mistakes, though, especially once the idea of "forwarding=20
references" (formerly known as "universal references") gains traction. Does=
=20
anyone have any examples or stories of cases in which a mistake was averted=
=20
by the above sanity-check?
=E2=80=93Arthur
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2533_51948094.1423506796035
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, February 8, 2015 at 10:25:12 PM UTC-8, Jim Port=
er wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2/9/2015 12:00 AM,=
Arthur O'Dwyer wrote:
<br>> This seems like a great idea to me!
<br>> Please post your implementation of forward_if, especially if it's
<br>> significantly different from this one.
<br>
<br>Here's my implementation (which has unit tests, but there's always the=
=20
<br>chance I got something wrong, since RVO can hide bugs here):
<br>
<br><font face=3D"courier new, monospace"> template<typename=
Container, typename Element>
<br> inline decltype(auto) move_if(Element &&value) {
<br> using Value =3D typename std::remove_reference<E=
lement><wbr>::type;
<br> using ReturnType =3D typename std::conditional<
<br> std::is_lvalue_reference<<wbr>Container&g=
t;::value, Value &, Value &&
<br> >::type;
<br> return static_cast<ReturnType>(value)<wbr>;
<br> }</font><br></blockquote><div><br></div><div>I just wanted=
to say: wow! That is WAY less code (and more readable, and more likely to =
be optimized) than my SFINAE version. Hooray for decltype(auto) and std::co=
nditional!</div><div>(Btw, I think you're unnecessarily worried about RVO; =
I can't think of any "bug" it might hide, here *or* in general.)</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;">> In fact, I woul=
d ask: Is there really any use-case for the existing
<br>> std::forward<T> that would break if we replaced std::forward=
<T>(t) with
<br>> std::forward_if<T>(t)? Could we just make std::forward in C+=
+1z behave
<br>> like the std::forward_if above, so that one library function will
<br>> suffice for both purposes?
<br>
<br>That should work, yes. I can see an argument that std::forward should=
=20
<br>remain as-is to prevent people from accidentally using the wrong type i=
n=20
<br>the template, but that might not be a major concern in reality.
<br></blockquote><div><br></div><div>The standard language (N4296) says:</d=
iv><div><br></div><div>
=09
=09
=09
<div class=3D"page" title=3D"Page 531">
<div class=3D"layoutArea">
<div class=3D"column">
<pre><span style=3D"font-size: 9.000000pt; font-family: 'LMMono9'">tem=
plate <class T> constexpr T&& forward(remove_reference_t<T=
>& t) noexcept;
template <class T> constexpr T&& forward(remove_reference_t&l=
t;T>&& t) noexcept;
</span></pre><pre><span style=3D"font-size: 9.000000pt; font-family: 'LMMon=
o9'"><br></span></pre>
</div>
</div>
</div></div><div><span style=3D"font-size: 10pt; line-height: 18px; font-=
family: LMRoman10; font-style: italic;">Returns: </span><span style=3D"font=
-size: 10pt; line-height: 18px; font-family: LMMono10;">static_cast<T&am=
p;&>(t)</span><span style=3D"font-size: 10pt; line-height: 18px; fon=
t-family: LMRoman10;">.</span></div>
=09
=09
=09
<div class=3D"page" title=3D"Page 531">
<div class=3D"layoutArea">
<div class=3D"column">
<p><span style=3D"font-size: 10.000000pt; font-family: 'LMRoman10'; fo=
nt-style: italic">Remark: </span><span style=3D"font-size: 10.000000pt; fon=
t-family: 'LMRoman10'">If the second form is instantiated with an lvalue re=
ference type, the program is ill-formed.</span></p>
</div>
</div>
</div><div>The remark forbids constructs such as <font face=3D"courier ne=
w, monospace">std::forward<T>(std::move(t))</font> (when <font face=
=3D"courier new, monospace">T&& t</font> was passed an lvalue) and =
<font face=3D"courier new, monospace">std::forward<int&>(42)</fon=
t>. Neither of these seem like common mistakes, though, especially once the=
idea of "forwarding references" (formerly known as "universal references")=
gains traction. Does anyone have any examples or stories of cases in which=
a mistake was averted by the above sanity-check?</div><div><br></div><div>=
=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2533_51948094.1423506796035--
------=_Part_2532_347673883.1423506796035--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 9 Feb 2015 13:00:35 -0600
Raw View
--089e0158b83a0509a5050eac65ec
Content-Type: text/plain; charset=UTF-8
On 9 February 2015 at 12:33, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
> template <class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
> template <class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
>
>
> Returns: static_cast<T&&>(t).
>
> Remark: If the second form is instantiated with an lvalue reference type,
> the program is ill-formed.
> The remark forbids constructs such as std::forward<T>(std::move(t))
> (when T&& t was passed an lvalue) and std::forward<int&>(42). Neither of
> these seem like common mistakes, though, especially once the idea of
> "forwarding references" (formerly known as "universal references") gains
> traction. Does anyone have any examples or stories of cases in which a
> mistake was averted by the above sanity-check?
>
The problem case is forgetting to explicitly specify the template
parameter, as in:
std::forward(t)
instead of
std::forward<T>(t)
In your specific example, std::forward(42) is ill-formed, and rightly so.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0158b83a0509a5050eac65ec
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">=
On 9 February 2015 at 12:33, Arthur O'Dwyer <span dir=3D"ltr"><<a hr=
ef=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@g=
mail.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><di=
v title=3D"Page 531"><div><div><pre><span style=3D"font-size:9.000000pt;fon=
t-family:'LMMono9'">template <class T> constexpr T&& =
forward(remove_reference_t<T>& t) noexcept;
template <class T> constexpr T&& forward(remove_reference_t&l=
t;T>&& t) noexcept;
</span></pre><pre><span style=3D"font-size:9.000000pt;font-family:'LMMo=
no9'"><br></span></pre>
</div>
</div>
</div></div><div><span style=3D"font-size:10pt;line-height:18px;font-fami=
ly:LMRoman10;font-style:italic">Returns: </span><span style=3D"font-size:10=
pt;line-height:18px;font-family:LMMono10">static_cast<T&&>(t)=
</span><span style=3D"font-size:10pt;line-height:18px;font-family:LMRoman10=
">.</span></div>
=09
=09
=09
<div title=3D"Page 531">
<div>
<div>
<p><span style=3D"font-size:10.000000pt;font-family:'LMRoman10'=
;;font-style:italic">Remark: </span><span style=3D"font-size:10.000000pt;fo=
nt-family:'LMRoman10'">If the second form is instantiated with an l=
value reference type, the program is ill-formed.</span></p>
</div>
</div>
</div><div>The remark forbids constructs such as <font face=3D"courier ne=
w, monospace">std::forward<T>(std::move(t))</font> (when <font face=
=3D"courier new, monospace">T&& t</font> was passed an lvalue) and =
<font face=3D"courier new, monospace">std::forward<int&>(42)</fon=
t>. Neither of these seem like common mistakes, though, especially once the=
idea of "forwarding references" (formerly known as "univers=
al references") gains traction. Does anyone have any examples or stori=
es of cases in which a mistake was averted by the above sanity-check?</div>=
</blockquote></div><br></div><div class=3D"gmail_extra">The problem case is=
forgetting to explicitly specify the template parameter, as in:<br><br></d=
iv><div class=3D"gmail_extra">std::forward(t)<br><br>instead of<br><br>std:=
:forward<T>(t)<br></div><div class=3D"gmail_extra"><br clear=3D"all">=
</div><div class=3D"gmail_extra">In your specific example, std::forward(42)=
is ill-formed, and rightly so.<br></div><div class=3D"gmail_extra">-- <br>=
<div class=3D"gmail_signature">=C2=A0Nevin ":-)" Liber=C2=A0 <=
mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@ev=
iloverlord.com</a>>=C2=A0 (847) 691-1404</div>
</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0158b83a0509a5050eac65ec--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 9 Feb 2015 16:05:30 -0800
Raw View
--f46d0444e9831c8834050eb0a59d
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Mon, Feb 9, 2015 at 11:00 AM, Nevin Liber <nevin@eviloverlord.com> wrote=
:
> On 9 February 2015 at 12:33, Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
wrote:
>>
>> template <class T> constexpr T&& forward(remove_reference_t<T>& t)
noexcept;
>> template <class T> constexpr T&& forward(remove_reference_t<T>&& t)
noexcept;
>>
>> Returns: static_cast<T&&>(t).
>>
>> Remark: If the second form is instantiated with an lvalue reference type=
,
>> the program is ill-formed.
>>
>> The remark forbids constructs such as std::forward<T>(std::move(t)) (whe=
n
>> T&& t was passed an lvalue) and std::forward<int&>(42). Neither of these
>> seem like common mistakes, though, especially once the idea of
"forwarding
>> references" (formerly known as "universal references") gains traction.
Does
>> anyone have any examples or stories of cases in which a mistake was
averted
>> by the above sanity-check?
>
>
> The problem case is forgetting to explicitly specify the template
parameter,
> as in:
>
> std::forward(t)
>
> instead of
>
> std::forward<T>(t)
>
> In your specific example, std::forward(42) is ill-formed, and rightly so.
Wait, that's not right! std::forward(42) without any angle brackets doesn't
work at all, because template parameter T can't be deduced. (The only thing
the compiler has to go on is that remove_reference_t<T> is int, but that's
not enough to nail down what T is.)
*x.cc:6:1: **error: **no matching function for call to 'forward'*
std::forward(42);
*^~~~~~~~~~~~*
*/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolc=
hain/usr/bin/../include/c++/v1/type_traits:1547:1:
note: *candidate template ignored: couldn't infer
template argument '_Tp'
forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
*^*
*/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolc=
hain/usr/bin/../include/c++/v1/type_traits:1555:1:
note: *candidate template ignored: couldn't infer
template argument '_Tp'
forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT
*^*
My suggestion of having std::forward behave like forward_if doesn't change
that behavior.
*x.cc:17:1: **error: **no matching function for call to 'forward'*
STD::forward(42);
*^~~~~~~~~~~~*
*x.cc:6:26: note: *candidate template ignored: couldn't infer template
argument 'Container'
inline decltype(auto) forward(Element &&value) {
* ^*
The difference *is* really with cases like std::forward<int&>(42).
=E2=80=93Arthur
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--f46d0444e9831c8834050eb0a59d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Feb 9, 2015 at 11:00 AM, Nevin Liber <<a href=
=3D"mailto:nevin@eviloverlord.com">nevin@eviloverlord.com</a>> wrote:<br=
>> On 9 February 2015 at 12:33, Arthur O'Dwyer <<a href=3D"mailto=
:arthur.j.odwyer@gmail.com">arthur.j.odwyer@gmail.com</a>> wrote:<br>>=
;><br>>> template <class T> constexpr T&& forward(re=
move_reference_t<T>& t) noexcept;<br>>> template <class =
T> constexpr T&& forward(remove_reference_t<T>&& t=
) noexcept;<br>>><br>>> Returns: static_cast<T&&>=
(t).<br>>><br>>> Remark: If the second form is instantiated wit=
h an lvalue reference type,<br>>> the program is ill-formed.<br>>&=
gt;<br>>> The remark forbids constructs such as std::forward<T>=
(std::move(t)) (when<br>>> T&& t was passed an lvalue) and st=
d::forward<int&>(42). Neither of these<br>>> seem like comm=
on mistakes, though, especially once the idea of "forwarding<br>>&g=
t; references" (formerly known as "universal references") ga=
ins traction. Does<br>>> anyone have any examples or stories of cases=
in which a mistake was averted<br>>> by the above sanity-check?<br>&=
gt;<br>><br>> The problem case is forgetting to explicitly specify th=
e template parameter,<br>> as in:<br>><br>> std::forward(t)<br>>=
;<br>> instead of<br>><br>> std::forward<T>(t)<br>><br>&g=
t; In your specific example, std::forward(42) is ill-formed, and rightly so=
..<br><br>Wait, that's not right! <font face=3D"monospace, monospace">st=
d::forward(42)</font> without any angle brackets doesn't work at all, b=
ecause template parameter <font face=3D"monospace, monospace">T</font> can&=
#39;t be deduced. (The only thing the compiler has to go on is that <font f=
ace=3D"monospace, monospace">remove_reference_t<T></font> is <font fa=
ce=3D"monospace, monospace">int</font>, but that's not enough to nail d=
own what <font face=3D"monospace, monospace">T</font> is.)<br><br><p style=
=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:6:1: </b><span sty=
le=3D"color:rgb(195,55,32)"><b>error: </b></span><b>no matching function fo=
r call to 'forward'</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">std::forward(42);<=
/p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^~~~~~~~~~~~</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>/Applications/X=
code.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../=
include/c++/v1/type_traits:1547:1: note: </b>candidate template ignored: co=
uldn't infer</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">=C2=A0 =C2=A0 =C2=
=A0 template argument '_Tp'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">forward(typename s=
td::remove_reference<_Tp>::type& __t) _NOEXCEPT</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>/Applications/X=
code.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../=
include/c++/v1/type_traits:1555:1: note: </b>candidate template ignored: co=
uldn't infer</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">=C2=A0 =C2=A0 =C2=
=A0 template argument '_Tp'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">forward(typename s=
td::remove_reference<_Tp>::type&& __t) _NOEXCEPT</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^</b></p><br><div>My suggestion of having <font face=3D"monospace, mo=
nospace">std::forward</font> behave like <font face=3D"monospace, monospace=
">forward_if</font> doesn't change that behavior.</div><div><br></div><=
div><p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:17:1: =
</b><span style=3D"color:rgb(195,55,32)"><b>error: </b></span><b>no matchin=
g function for call to 'forward'</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">STD::forward(42);<=
/p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^~~~~~~~~~~~</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:6:26: note=
: </b>candidate template ignored: couldn't infer template argument '=
;Container'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">=C2=A0=C2=A0 inlin=
e decltype(auto) forward(Element &&value) {=C2=A0</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>=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 ^</b></p><div><br></div><div>The difference <i>is</i> =
really with cases like <font face=3D"monospace, monospace">std::forward<=
int&>(42)</font>.</div></div><div><br></div><div>=E2=80=93Arthur</di=
v></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d0444e9831c8834050eb0a59d--
.
Author: Scott Prager <splinterofchaos@gmail.com>
Date: Tue, 10 Feb 2015 10:46:22 -0800 (PST)
Raw View
------=_Part_748_558826209.1423593982523
Content-Type: multipart/alternative;
boundary="----=_Part_749_1246106332.1423593982523"
------=_Part_749_1246106332.1423593982523
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, February 9, 2015 at 7:05:32 PM UTC-5, Arthur O'Dwyer wrote:
=20
> Wait, that's not right! std::forward(42) without any angle brackets=20
> doesn't work at all, because template parameter T can't be deduced. (The=
=20
> only thing the compiler has to go on is that remove_reference_t<T> is int=
,=20
> but that's not enough to nail down what T is.)
>
> *x.cc:6:1: **error: **no matching function for call to 'forward'*
>
> std::forward(42);
>
> *^~~~~~~~~~~~*
>
> */Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoo=
lchain/usr/bin/../include/c++/v1/type_traits:1547:1:=20
> note: *candidate template ignored: couldn't infer
>
> template argument '_Tp'
>
> forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT
>
> *^*
>
> */Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoo=
lchain/usr/bin/../include/c++/v1/type_traits:1555:1:=20
> note: *candidate template ignored: couldn't infer
>
> template argument '_Tp'
>
> forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT
>
> *^*
>
> My suggestion of having std::forward behave like forward_if doesn't=20
> change that behavior.
>
> *x.cc:17:1: **error: **no matching function for call to 'forward'*
>
> STD::forward(42);
>
> *^~~~~~~~~~~~*
>
> *x.cc:6:26: note: *candidate template ignored: couldn't infer template=20
> argument 'Container'
>
> inline decltype(auto) forward(Element &&value) {=20
>
> * ^*
>
> The difference *is* really with cases like std::forward<int&>(42).
>
Or how about a cases like *std::forward<Apple>(orange)*?
This *forward_if* function really means "move if this other type, which=20
likely
has no relation to the argument, is not a reference type"--these semantics
feel too uncomfortable for use as a general case, and even calling it
*forward_if* or *move_if* implies a much more general concept than being
discussed here.
> =E2=80=93Arthur
>
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_749_1246106332.1423593982523
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, February 9, 2015 at 7:05:32 PM UTC-5, A=
rthur O'Dwyer wrote:<div> </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">Wait, that's not right! <font face=3D"monospace, mo=
nospace">std::forward(42)</font> without any angle brackets doesn't work at=
all, because template parameter <font face=3D"monospace, monospace">T</fon=
t> can't be deduced. (The only thing the compiler has to go on is that <fon=
t face=3D"monospace, monospace">remove_reference_t<T></font> is <font=
face=3D"monospace, monospace">int</font>, but that's not enough to nail do=
wn what <font face=3D"monospace, monospace">T</font> is.)<br><br><p style=
=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:6:1: </b><span sty=
le=3D"color:rgb(195,55,32)"><b>error: </b></span><b>no matching function fo=
r call to 'forward'</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">std::forward(42);<=
/p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^~~~~~~~~~~~</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>/Applications/X=
code.app/<wbr>Contents/Developer/Toolchains/<wbr>XcodeDefault.xctoolchain/u=
sr/<wbr>bin/../include/c++/v1/type_<wbr>traits:1547:1: note: </b>candidate =
template ignored: couldn't infer</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"> &nbs=
p; template argument '_Tp'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">forward(typename s=
td::remove_reference<_Tp>::<wbr>type& __t) _NOEXCEPT</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>/Applications/X=
code.app/<wbr>Contents/Developer/Toolchains/<wbr>XcodeDefault.xctoolchain/u=
sr/<wbr>bin/../include/c++/v1/type_<wbr>traits:1555:1: note: </b>candidate =
template ignored: couldn't infer</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"> &nbs=
p; template argument '_Tp'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">forward(typename s=
td::remove_reference<_Tp>::<wbr>type&& __t) _NOEXCEPT</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^</b></p><br><div>My suggestion of having <font face=3D"monospace, mo=
nospace">std::forward</font> behave like <font face=3D"monospace, monospace=
">forward_if</font> doesn't change that behavior.</div><div><br></div><div>=
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:17:1: </b>=
<span style=3D"color:rgb(195,55,32)"><b>error: </b></span><b>no matching fu=
nction for call to 'forward'</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo">STD::forward(42);<=
/p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b>^~~~~~~~~~~~</b></p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"><b>x.cc:6:26: note=
: </b>candidate template ignored: couldn't infer template argument 'Contain=
er'</p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo"> inlin=
e decltype(auto) forward(Element &&value) { </p>
<p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,189,38=
)"><b> =
^</b></p><div><br></div><div>The difference <i>is</i> =
really with cases like <font face=3D"monospace, monospace">std::forward<=
int&>(42)</font>.</div></div></div></blockquote><div><br></div><div>=
Or how about a cases like <i>std::forward<Apple>(orange)</i>?</div><d=
iv><br></div><div>This <i>forward_if</i> function really means "move i=
f this other type, which likely</div><div>has no relation to the argument, =
is not a reference type"--these semantics</div><div>feel too uncomfortable =
for use as a general case, and even calling it</div><div><i>forward_if</i>&=
nbsp;or <i>move_if</i> implies a much more general concept than being<=
/div><div>discussed here.</div><div><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>=E2=80=93Arthur</div><=
/div>
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_749_1246106332.1423593982523--
------=_Part_748_558826209.1423593982523--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 10 Feb 2015 14:24:24 -0800
Raw View
--f46d043890795ef36d050ec35969
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tue, Feb 10, 2015 at 10:46 AM, Scott Prager <splinterofchaos@gmail.com>
wrote:
> On Monday, February 9, 2015 at 7:05:32 PM UTC-5, Arthur O'Dwyer wrote:
>
>
>> The difference [between forward and forward_if] *is* really with cases
>> like std::forward<int&>(42).
>>
>
> Or how about a cases like *std::forward<Apple>(orange)*?
>
That's the case that is currently a compiler error =E2=80=94 but only throu=
gh an
"accident", in the sense that there's no standardese specifically calling
it out as undesirable. The point of your "option (1)", the one that I'm
vehemently agreeing with, is that this case is not only "not undesirable"
to support, but actually *very desirable* to support.
This *forward_if* function really means "move if this other type, which
> likely
> has no relation to the argument, is not a reference type"--these semantic=
s
> feel too uncomfortable for use as a general case, and even calling it
> *forward_if* or *move_if* implies a much more general concept than being
> discussed here.
>
I would disagree with your intuition here. "Forward" and "move" are not
really the same concept, which is why I also disagree with your originally
naming the construct "move_if" instead of "forward_if". The appropriate
intuition IMO is not that we're "conditionally moving from" the argument;
that's the domain of "move_if_noexcept" and such. The appropriate intuition
is that we're doing whatever is required to "forward" the argument on to
the callee. Sometimes that involves casting to an rvalue reference,
sometimes it doesn't.
Further muddying the waters... a third option would be to introduce
std::move_if<bool
Cond>(x), which would move from x if and only if Cond. If I'm not
mistaken, this would allow both std::forward and std::move_if_noexcept to
be implemented in terms of std::move_if.
But I'm not sure there's enough of a market for that "generalized
std::move_if".
=E2=80=93Arthur
--=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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--f46d043890795ef36d050ec35969
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tue, Feb 10, 2015 at 10:46 AM, Scott Prager <span dir=
=3D"ltr"><<a href=3D"mailto:splinterofchaos@gmail.com" target=3D"_blank"=
>splinterofchaos@gmail.com</a>></span> wrote:<br><div class=3D"gmail_ext=
ra"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">On Monday, February 9, 2015 at 7:05:32 PM UTC-5, Arthur O'Dwyer wro=
te:<br><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"><p style=3D"margin:0px;font-size:11px;font-family:Menlo;color:rgb(52,=
189,38)"><span style=3D"font-family:arial,sans-serif;font-size:small;color:=
rgb(34,34,34)">The difference [between forward and forward_if]=C2=A0</span>=
<i style=3D"font-family:arial,sans-serif;color:rgb(34,34,34)">is</i><span s=
tyle=3D"font-family:arial,sans-serif;font-size:small;color:rgb(34,34,34)"> =
really with cases like </span><font face=3D"monospace, monospace" style=3D"=
color:rgb(34,34,34)">std::forward<int&>(42)</font><span style=3D"=
font-family:arial,sans-serif;font-size:small;color:rgb(34,34,34)">.</span><=
br></p></div></blockquote><div><br></div><div>Or how about a cases like <i>=
std::forward<Apple>(orange)</i>?</div></div></blockquote><div>=C2=A0<=
/div><div>That's the case that is currently a compiler error =E2=80=94 =
but only through an "accident", in the sense that there's no =
standardese specifically calling it out as undesirable. The point of your &=
quot;option (1)", the one that I'm vehemently agreeing with, is th=
at this case is not only "not undesirable" to support, but actual=
ly <b>very desirable</b> to support.</div><div><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></div><div>This <i>forward_if</i>=C2=A0=
function really means "move if this other type, which likely</div><div=
>has no relation to the argument, is not a reference type"--these sema=
ntics</div><div>feel too uncomfortable for use as a general case, and even =
calling it</div><div><i>forward_if</i>=C2=A0or <i>move_if</i>=C2=A0implies =
a much more general concept than being</div><div>discussed here.</div></div=
></blockquote><div><br></div><div>I would disagree with your intuition here=
.. "Forward" and "move" are not really the same concept,=
which is why I also disagree with your originally naming the construct &qu=
ot;move_if" instead of "forward_if". The appropriate intuiti=
on IMO is not that we're "conditionally moving from" the argu=
ment; that's the domain of "move_if_noexcept" and such. The a=
ppropriate intuition is that we're doing whatever is required to "=
forward" the argument on to the callee. Sometimes that involves castin=
g to an rvalue reference, sometimes it doesn't.</div><div><br></div><di=
v>Further muddying the waters... a third option would be to introduce=C2=A0=
<font face=3D"monospace, monospace">std::move_if<bool Cond>(x)</font>=
, which would move from x if and only if Cond.=C2=A0 If I'm not mistake=
n, this would allow both std::forward and std::move_if_noexcept to be imple=
mented in terms of std::move_if.</div><div><br></div><div>But I'm not s=
ure there's enough of a market for that "generalized std::move_if&=
quot;.</div><div><br></div><div>=E2=80=93Arthur</div><div><br></div></div><=
/div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--f46d043890795ef36d050ec35969--
.