Topic: n3351 Function and <algorithm> concept requirements
Author: Scott Prager <splinterofchaos@gmail.com>
Date: Wed, 4 Feb 2015 10:41:45 -0800 (PST)
Raw View
------=_Part_729_456637322.1423075305919
Content-Type: multipart/alternative;
boundary="----=_Part_730_1744400123.1423075305919"
------=_Part_730_1744400123.1423075305919
Content-Type: text/plain; charset=UTF-8
Hi, I'm going off
of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf ,
as linked
from http://ericniebler.com/2015/01/28/to-be-or-not-to-be-an-iterator/ ,
so if there's a more up-to-date version, this may be moot, but...
The suggested signature of *std::for_each*:
template<InputIterator I, Function<F, ValueType<I>> F>
F for_each(I first, I last, F f);
Particularly, I feel that *Function<F, ValueType<I>>* doesn't make sense.
The concept requirements of *Function*:
concept Function<typename F, typename... Args> =
// [snip]
requires callable(F f, Args args...) {
ResultType<F, Args...> == { f(args...) };
};
I must admit that I haven't read the proposal cover-to-cover, but I
interpret this concept
as meaning that given the variables, *args, *the expression, *f(args...)* will
result in exactly
the same type of *std::result_of_t<F(Args...)>,* but I can think of a
fairly trivial example
that would be valid code, but fail the concept check.
struct id_f {
template<typename X>
X&& operator () (X&& x) const {
return std::forward<X>(x);
}
};
Function<id_f, int>
=> callable(id_f id, int x) {
ResultType<id_f, int> == { id(x) };
};
ResultType<id_f, int> = int&&
{ id(x) } = int&
For another example,
int main() {
std::vector<X> v, w = { ... };
std::for_each(std::make_move_iterator(w.begin()), std::make_move_iterator(
w.end()),
[&](X&& x) { v.emplace_back(std::move(x)); });
}
Let's say that *X* is a move-only type. The concept, however, will check
*{ lambda(x) } *and since *x* will reduce to a reference, the expression
will be
invalid and this code will be rejected.
So, I would prefer to assume that the *Function* concept should be written
like this:
concept Function<typename F, typename... Args> =
// [snip]
requires callable(F f, Args args...) {
ResultType<F, Args...> == { f(std::forward<Args>(args)...) };
};
and this would allow *Function<id_f, int>* to pass the *callable* requirement.
But going back to *for_each*...
template<InputIterator I, Function<F, ValueType<I>> F>
F for_each(I first, I last, F f);
Now, let *f* be a function that takes its value by reference. *ResultType<F,
ValueType<I>>*
is no longer valid the expression *{ f(val{}) }* will try to bind a
non-const reference to
an rvalue.
So, if I'm reading this all correctly, the concept of *Function* must be
rewritten
to perfect-forward the arguments in the *callable* requirement lest any
code requiring
*F* to take an rvalue reference be marked invalid. Also, the requirements of
*<algorithm>* functions must be changed to check the concepts against the
iterator's
reference type, rather than the value type, so that functions expecting a
reference
would continue to meet the callable requirement after the above change.
In response to some commonts along these lines, Eric Niebler noted that
The idea is to express relationships between types, not between
> expressions.
To make this a bit more concrete: some algorithms have to make local copies
of some elements (e.g., unique_copy on an Input sequence). If you've done
> all
your type-checking with the ReferenceType, then what can you do with a
> local
object of the ValueType?
(link)
<http://www.reddit.com/r/cpp/comments/2u259e/the_problems_with_proxy_iterators_ericnieblercom/co4qczn>
and that very much mirrors the language of n3351, specifically that in
section 1.3.
Making concepts based on exact semantic requirements leads to verbosity,
while using high-level abstractions can be too constraining. so a middle
ground
was chosen.
So, have I been reading this wrong or made some grievous mistake in my
logic,
is there perhaps another version of n3351 I should be considering, past
discussion
on this topic I should consult? (I did search, but didn't find any relating
to this
point.)
--
---
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_730_1744400123.1423075305919
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi, I'm going off of http://www.open-std.org/jtc1/sc2=
2/wg21/docs/papers/2012/n3351.pdf , <div>as linked from http://er=
icniebler.com/2015/01/28/to-be-or-not-to-be-an-iterator/ , </div><div>=
so if there's a more up-to-date version, this may be moot, but...<div><br><=
/div><div>The suggested signature of <i>std::for_each</i>:</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 clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify"><</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">InputIterator</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> I</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Function</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">ValueType</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">I</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">>></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>F for_each</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">I first</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> I </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">last</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> F f</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span></div></code></div><div><=
div><br></div></div><div>Particularly, I feel that <i>Function<F, ValueT=
ype<I>></i> doesn't make sense.</div><div>The concept require=
ments of <i>Function</i>:</div><div><br></div><div><div class=3D"prettyprin=
t" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; ba=
ckground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">concept</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Function<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">typename</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">typename</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-b=
y-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> </spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// [snip]</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> requi=
res callable</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F f</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> args</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">...)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">ResultType</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">F</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">...></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>args</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: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span></div></code></div=
><div><br></div></div><div>I must admit that I haven't read the proposal co=
ver-to-cover, but I interpret this concept</div><div>as meaning that given =
the variables, <i>args, </i>the expression, <i>f(args...)</i> will res=
ult in exactly</div><div>the same type of <i>std::result_of_t<F(Args...)=
>,</i> but I can think of a fairly trivial example</div><div>that w=
ould be valid code, but fail the concept check.</div><div><br></div><div cl=
ass=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wra=
p: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><font color=3D"#000088"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> id_f </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span></font><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=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">typename</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> X</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br> X</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">&&</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">opera=
tor</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">()</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">X</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">co=
nst</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br> </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">forward</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">X</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">>(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">x</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-prettif=
y">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span=
style=3D"color: #606;" class=3D"styled-by-prettify">Function</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">id_f</span><span style=3D"co=
lor: #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">int</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> callable</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">i=
d_f id</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">int</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x</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"col=
or: #606;" class=3D"styled-by-prettify">ResultType</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">id_f</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</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"> id</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</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: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br></span><span style=3D"color: #606;" class=3D"styled-by-prettify">Result=
Type</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">id_f</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </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"=
>int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&&=
amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> id</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">x</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=
"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&</span></div></code></div><div><br></div><div>For another =
example,</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1p=
x solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(25=
0, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> main</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;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">vector</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">X</span><span style=3D"color: #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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> w </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">...</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> std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">for_each</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">make_move_iterator</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">w</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">begin</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">()),</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">make_move_itera=
tor</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">w</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">end</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">()),</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br> &=
nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">[&](</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>X</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&&am=
p;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #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"style=
d-by-prettify">emplace_back</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">x</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;" c=
lass=3D"styled-by-prettify">});</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span></div></code></div><div><br></div><div>Let's say tha=
t <i>X</i> is a move-only type. The concept, however, will check =
</div><div><i>{ lambda(x) } </i>and since <i>x</i> will reduce to a re=
ference, the expression will be</div><div>invalid and this code will be rej=
ected.</div><div><br></div><div>So, I would prefer to assume that the <i>Fu=
nction</i> concept should be written like this:</div><div><br></div><d=
iv class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); wor=
d-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">concept</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Function</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</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"> F</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">typename</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=
: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br> </span><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// [snip]</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br> requires callable</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">F f</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> args</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">...)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">ResultType</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">F</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">...></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</s=
pan><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"> f</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=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-b=
y-prettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"><</span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">Args</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>=
;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">args</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)...)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=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"col=
or: #660;" class=3D"styled-by-prettify">};</span></div></code></div><br>and=
this would allow <i>Function<id_f, int></i> to pass the <i>call=
able</i> requirement. But going back to <i>for_each</i>...<div style=
=3D"font-size: 13.3333339691162px;"><br></div><div class=3D"prettyprint" st=
yle=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backgro=
und-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"s=
ubprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">te=
mplate</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">InputItera=
tor</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> I</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">Function</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">F</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">ValueType</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify"><</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
I</span><span style=3D"color: #660;" class=3D"styled-by-prettify">>><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> F</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>F for_each</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">I first</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> I </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">last</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> F f</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></div></code></div><div style=3D"font-size: 13.3333339691162px;=
"><br></div><div style=3D"font-size: 13.3333339691162px;">Now, let <i>f</i>=
be a function that takes its value by reference. <span style=3D"=
font-size: 13.3333339691162px;"><i>ResultType<F, ValueType<I>><=
/i></span></div><div style=3D"font-size: 13.3333339691162px;">is no longer =
valid the expression <i>{ f(val{}) }</i> will try to bind a non-const =
reference to</div><div style=3D"font-size: 13.3333339691162px;">an rvalue.&=
nbsp;</div><div style=3D"font-size: 13.3333339691162px;"><br></div><div sty=
le=3D"font-size: 13.3333339691162px;">So, if I'm reading this all correctly=
, the concept of <i>Function</i> must be rewritten</div><div style=3D"=
font-size: 13.3333339691162px;">to perfect-forward the arguments in the <i>=
callable</i> requirement lest any code requiring</div><div style=3D"fo=
nt-size: 13.3333339691162px;"><i>F</i> to take an rvalue reference be =
marked invalid. Also, the requirements of</div><div style=3D"font-size: 13.=
3333339691162px;"><i><algorithm></i> functions must be changed t=
o check the concepts against the iterator's</div><div style=3D"font-size: 1=
3.3333339691162px;">reference type, rather than the value type, so that fun=
ctions expecting a reference</div><div style=3D"font-size: 13.3333339691162=
px;">would continue to meet the callable requirement after the above change=
..</div><div style=3D"font-size: 13.3333339691162px;"><br></div><div style=
=3D"font-size: 13.3333339691162px;">In response to some commonts along thes=
e lines, Eric Niebler noted that </div><div style=3D"font-size: 13.333=
3339691162px;"><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204=
, 204); border-left-style: solid; padding-left: 1ex;">The idea is to expres=
s relationships between types, not between expressions. </blockquote><=
blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border=
-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style:=
solid; padding-left: 1ex;">To make this a bit more concrete: some algorith=
ms have to make local copies </blockquote><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-le=
ft-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"=
>of some elements (e.g., unique_copy on an Input sequence). If you've done =
all </blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0p=
x 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 2=
04); border-left-style: solid; padding-left: 1ex;">your type-checking with =
the ReferenceType, then what can you do with a local </blockquote><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-le=
ft-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: so=
lid; padding-left: 1ex;">object of the ValueType?</blockquote><div><br></di=
v><div><a href=3D"http://www.reddit.com/r/cpp/comments/2u259e/the_problems_=
with_proxy_iterators_ericnieblercom/co4qczn">(link) </a></div><div><br=
></div><div>and that very much mirrors the language of n3351, specifically =
that in section 1.3.</div><div>Making concepts based on exact semantic requ=
irements leads to verbosity,</div><div>while using high-level abstractions =
can be too constraining. so a middle ground</div><div>was chosen.</div><div=
><br></div><div>So, have I been reading this wrong or made some grievous mi=
stake in my logic,</div><div>is there perhaps another version of n3351 I sh=
ould be considering, past discussion</div><div>on this topic I should consu=
lt? (I did search, but didn't find any relating to this</div><div>point.)&n=
bsp;</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 />
------=_Part_730_1744400123.1423075305919--
------=_Part_729_456637322.1423075305919--
.