Topic: Proposal for additional generic behaviour when
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 22 Nov 2012 15:51:21 -0800 (PST)
Raw View
------=_Part_93_11395202.1353628281288
Content-Type: text/plain; charset=ISO-8859-1
This proposal primarily aims to remove the differences between functions,
and function objects. Right now, the only reason to use functions is
explicit template arguments, and because they are more convenient to
specify. Else, function objects are superior in every way, as they are more
convenient to use, more flexible, and can be more efficient, as function
pointers can interfere with inlining and such optimizations.
I propose that, in alteration of what is currently defined, the name of a
function in fact refers to a function object of undefined type. When that
function object is invoked, it forwards all of it's arguments to that
function. For member functions, this is implicitly stored as a reference,
not a copy. For example, consider a trivial example:
template<typename T> bool less(T lhs, T rhs) { return lhs < rhs; }
Currently, if you wish to pass this function as a function object to
std::sort, it must be instantiated with a type at the pass site to generate
a function pointer, which is often undesirable. Not only does it have the
potential to interfere with inlining and other optimizations if a compiler
is not sufficiently intelligent, but you have to know T in advance and
explicitly specify it. A function object does not have this drawback. It
would now be possible to call
std::sort(begin, end, less);
Here, the compiler would effectively generate a function object similar to
the following:
struct __some_internal_type {
template<typename... Args> auto operator()(Args&&... args) ->
decltype(less(std::forward<Args>(args)...)) {
return less(std::forward<Args>(args)...);
}
};
std::sort(begin, end, __some_internal_type());
In order to preserve legacy code, a conversion to function pointers of an
appropriate type must of course be specified. It would be quite possible to
do something similar with a polymorphic lambda, except that the lambda
would have to be repeatedly implemented at every call site with all the
boilerplate that involves. For a member, this would look more like
struct X {
template<typename T> bool less(T lhs, T rhs) { return lhs < rhs; }
};
std::sort(begin, end, (expression that yields an lvalue or rvalue x).less);
For a pointer to X, then
std::sort(begin, end, (expression that yields an X*)->less);
For another example, if proposals to allow type deduction on non-lambdas
are accepted, it would now be possible to write a freestanding function
which can be chained indefinitely.
auto f(int i) {
std::cout << i;
return f;
}
int main() {
f(5)(5)(5)(5)(5)(5)(5); // arbitrary
}
These proposed changes would significantly simplify the use of functions as
function parameters and bring their usability up to a par with function
objects.
--
------=_Part_93_11395202.1353628281288
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
This proposal primarily aims to remove the differences between functions, a=
nd function objects. Right now, the only reason to use functions is explici=
t template arguments, and because they are more convenient to specify. Else=
, function objects are superior in every way, as they are more convenient t=
o use, more flexible, and can be more efficient, as function pointers can i=
nterfere with inlining and such optimizations.<div><br></div><div>I propose=
that, in alteration of what is currently defined, the name of a function i=
n fact refers to a function object of undefined type. When that function ob=
ject is invoked, it forwards all of it's arguments to that function. For me=
mber functions, this is implicitly stored as a reference, not a copy. For e=
xample, consider a trivial example:</div><div><br></div><div>template<ty=
pename T> bool less(T lhs, T rhs) { return lhs < rhs; }</div><div><br=
></div><div>Currently, if you wish to pass this function as a function obje=
ct to std::sort, it must be instantiated with a type at the pass site to ge=
nerate a function pointer, which is often undesirable. Not only does it hav=
e the potential to interfere with inlining and other optimizations if a com=
piler is not sufficiently intelligent, but you have to know T in advance an=
d explicitly specify it. A function object does not have this drawback. It =
would now be possible to call</div><div><br></div><div>std::sort(begin, end=
, less);</div><div><br></div><div>Here, the compiler would effectively gene=
rate a function object similar to the following:</div><div><br></div><div>s=
truct __some_internal_type {<br> template<typename... Args&=
gt; auto operator()(Args&&... args) -> decltype(less(std::forwar=
d<Args>(args)...)) {</div><div> return les=
s(std::forward<Args>(args)...);</div><div> }<br>};</div>=
<div><br></div><div>std::sort(begin, end, __some_internal_type());</div><di=
v><br></div><div>In order to preserve legacy code, a conversion to function=
pointers of an appropriate type must of course be specified. It would be q=
uite possible to do something similar with a polymorphic lambda, except tha=
t the lambda would have to be repeatedly implemented at every call site wit=
h all the boilerplate that involves. For a member, this would look more lik=
e</div><div><br></div><div>struct X {</div><div> template<t=
ypename T> bool less(T lhs, T rhs) { return lhs < rhs; }<br></div><di=
v>};</div><div>std::sort(begin, end, (expression that yields an lvalue or r=
value x).less);</div><div><br></div><div>For a pointer to X, then</div><div=
><br></div><div>std::sort(begin, end, (expression that yields an X*)->le=
ss);</div><div><br></div><div>For another example, if proposals to allow ty=
pe deduction on non-lambdas are accepted, it would now be possible to write=
a freestanding function which can be chained indefinitely.</div><div><br><=
/div><div>auto f(int i) {</div><div> std::cout << i;</di=
v><div> return f;</div><div>}</div><div>int main() {</div><div=
> f(5)(5)(5)(5)(5)(5)(5); // arbitrary</div><div>}</div><div><=
br></div><div>These proposed changes would significantly simplify the use o=
f functions as function parameters and bring their usability up to a par wi=
th function objects.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_93_11395202.1353628281288--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 22 Nov 2012 17:09:45 -0800 (PST)
Raw View
------=_Part_1436_21423219.1353632985994
Content-Type: text/plain; charset=ISO-8859-1
On Thursday, November 22, 2012 3:51:21 PM UTC-8, DeadMG wrote:
>
> This proposal primarily aims to remove the differences between functions,
> and function objects. Right now, the only reason to use functions is
> explicit template arguments, and because they are more convenient to
> specify. Else, function objects are superior in every way, as they are more
> convenient to use, more flexible, and can be more efficient, as function
> pointers can interfere with inlining and such optimizations.
>
> I propose that, in alteration of what is currently defined, the name of a
> function in fact refers to a function object of undefined type. When that
> function object is invoked, it forwards all of it's arguments to that
> function.
>
Perfect forwarding is not perfect in terms of performance. Perfect
forwarding breaks input copy elision; if you have this function:
void SomeFunc(std::string str);
And you call it like this:
SomeFunc({"A String"});
The compiler can construct the temporary in-place. There will be no copying
or moving of the function argument on such compilers.
However, if you use perfect forwarding, perfect forwarding via template
argument deduction will effectively work like this:
void SomeFuncFwd(std::string &&str) {SomeFunc(std::move(str));}
This will cause a *move* where there didn't need to be one.
Perfect forwarding is perfect in terms of semantics, not performance. A
compiler-generated forwarding function *might* be able to be more perfect,
but if that problem isn't dealt with, it's a non-starter.
For member functions, this is implicitly stored as a reference, not a copy.
> For example, consider a trivial example:
>
> template<typename T> bool less(T lhs, T rhs) { return lhs < rhs; }
>
> Currently, if you wish to pass this function as a function object to
> std::sort, it must be instantiated with a type at the pass site to generate
> a function pointer, which is often undesirable. Not only does it have the
> potential to interfere with inlining and other optimizations if a compiler
> is not sufficiently intelligent, but you have to know T in advance and
> explicitly specify it. A function object does not have this drawback. It
> would now be possible to call
>
> std::sort(begin, end, less);
>
I want to make sure I understand something here. You want to make *massive*changes to the way functions work, which will cause a number of issues (as
I'll explain in a bit), all just so that you don't have to type this:
struct less
{
template<typename T> bool operator()(T lhs, T rhs) { return lhs < rhs; }
};
The difference between these is the location of the name, the use of
`struct {};`, the use of `operator()`, and the fact that calling it
requires you to use `less()` to create an instance.
You are talking about a change that will be *far* from transparent for
users. All so that you don't have to write `struct` quite so often. I don't
think it's worth it.
Here, the compiler would effectively generate a function object similar to
> the following:
>
> struct __some_internal_type {
> template<typename... Args> auto operator()(Args&&... args) ->
> decltype(less(std::forward<Args>(args)...)) {
> return less(std::forward<Args>(args)...);
> }
> };
>
> std::sort(begin, end, __some_internal_type());
>
> In order to preserve legacy code, a conversion to function pointers of an
> appropriate type must of course be specified.
>
So, what happens to this code?
void SomeFunc(int);
auto GetFunctor() -> std::function<decltype(SomeFunc)> { return {SomeFunc};}
In C++11, decltype(SomeFunc) is a *function* type, and is therefore legal
as a parameter to std::function. In your proposed revision, it isn't; it's
an object type. Which cannot be the type provided to a std::function.
This should be an opt-in mechanism, not a magical "everything that used to
work one way works *completely* differently now thing. If you want it, you
should have to ask for it in the declaration, using syntax like so:
void ThisIsAFunction();
void ThisIsAFunctor() functor;
At which point, you don't have to deal with decaying to function pointers
(though it could be allowed for non-template functors) or even the
forwarding stuff anymore. We understand that `ThisIsAFunctor` declares an
empty POD class type which has an overloaded `operator()` with the contents
you provide. A global variable called `ThisIsAFunctor` will be
instantiated, which is admittedly going to take some *very* creative
wording to pull off, since you now have to deal with what happens when you
stick one of these in a header. Is it externed everywhere? So which
translation unit defines it?
There would be no function overloading as well, which is another thing that
confounds your idea, since overloading is something that can happen in
different translation units in different ways (different TLs can see
different sets of functions with the same name). Type definitions can't be
spread across translation units, so if you wanted to group them all in a
type definition, you'd have a problem.
`functor` would be one of those "contextual identifier" things like "final"
and "override". So we wouldn't even need a keyword.
> It would be quite possible to do something similar with a polymorphic
> lambda, except that the lambda would have to be repeatedly implemented at
> every call site with all the boilerplate that involves. For a member, this
> would look more like
>
> struct X {
> template<typename T> bool less(T lhs, T rhs) { return lhs < rhs; }
> };
> std::sort(begin, end, (expression that yields an lvalue or rvalue x).less);
>
> For a pointer to X, then
>
> std::sort(begin, end, (expression that yields an X*)->less);
>
> For another example, if proposals to allow type deduction on non-lambdas
> are accepted, it would now be possible to write a freestanding function
> which can be chained indefinitely.
>
> auto f(int i) {
> std::cout << i;
> return f;
> }
> int main() {
> f(5)(5)(5)(5)(5)(5)(5); // arbitrary
> }
>
> These proposed changes would significantly simplify the use of functions
> as function parameters and bring their usability up to a par with function
> objects.
>
--
------=_Part_1436_21423219.1353632985994
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Thursday, November 22, 2012 3:51:21 PM UTC-8, DeadMG wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;">This proposal primarily aims to remove the =
differences between functions, and function objects. Right now, the only re=
ason to use functions is explicit template arguments, and because they are =
more convenient to specify. Else, function objects are superior in every wa=
y, as they are more convenient to use, more flexible, and can be more effic=
ient, as function pointers can interfere with inlining and such optimizatio=
ns.<div><br></div><div>I propose that, in alteration of what is currently d=
efined, the name of a function in fact refers to a function object of undef=
ined type. When that function object is invoked, it forwards all of it's ar=
guments to that function.</div></blockquote><div><br>Perfect forwarding is =
not perfect in terms of performance. Perfect forwarding breaks input copy e=
lision; if you have this function:<br><br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">SomeFunc</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> str</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></div></code></di=
v><br>And you call it like this:<br><br><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #606;"=
class=3D"styled-by-prettify">SomeFunc</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">({</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">"A String"</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">});</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span></div></code></div><br>The compiler can construct t=
he temporary in-place. There will be no copying or moving of the function a=
rgument on such compilers.<br><br>However, if you use perfect forwarding, p=
erfect forwarding via template argument deduction will effectively work lik=
e this:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">SomeFuncFwd<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an 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: #008;" class=3D"styled-by-prettify">string</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;" cl=
ass=3D"styled-by-prettify">str</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: #606;" class=3D"styled-by-prettify">SomeFun=
c</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 st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">move</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">str</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">));}</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span></div></code></div><br>This will cause a <i>move</=
i> where there didn't need to be one.<br><br>Perfect forwarding is perfect =
in terms of semantics, not performance. A compiler-generated forwarding fun=
ction <i>might</i> be able to be more perfect, but if that problem isn't de=
alt with, it's a non-starter.<br><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div> For member functions, this is implicitly stored as a ref=
erence, not a copy. For example, consider a trivial example:</div><div><br>=
</div><div>template<typename T> bool less(T lhs, T rhs) { return lhs =
< rhs; }</div><div><br></div><div>Currently, if you wish to pass this fu=
nction as a function object to std::sort, it must be instantiated with a ty=
pe at the pass site to generate a function pointer, which is often undesira=
ble. Not only does it have the potential to interfere with inlining and oth=
er optimizations if a compiler is not sufficiently intelligent, but you hav=
e to know T in advance and explicitly specify it. A function object does no=
t have this drawback. It would now be possible to call</div><div><br></div>=
<div>std::sort(begin, end, less);</div></blockquote><div><br>I want to make=
sure I understand something here. You want to make <i>massive</i> changes =
to the way functions work, which will cause a number of issues (as I'll exp=
lain in a bit), all just so that you don't have to type this:<br><br><div c=
lass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-=
color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wra=
p: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><=
span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> less<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: #008;" class=3D"styled-by-prettify">template</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" cla=
ss=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">bool</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">oper=
ator</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()(</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">T lhs</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> T rhs</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;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> lhs </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> rhs</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span></div></code></div><br>The difference betwe=
en these is the location of the name, the use of `struct {};`, the use of `=
operator()`, and the fact that calling it requires you to use `less()` to c=
reate an instance.<br><br>You are talking about a change that will be <i>fa=
r</i> from transparent for users. All so that you don't have to write `stru=
ct` quite so often. I don't think it's worth it.<br><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div></div><div>Here, the compiler would ef=
fectively generate a function object similar to the following:</div><div><b=
r></div><div>struct __some_internal_type {<br> template<typ=
ename... Args> auto operator()(Args&&... args) -> decltype(le=
ss(std::forward<<wbr>Args>(args)...)) {</div><div>  =
; return less(std::forward<Args>(args).<wbr>..);</div><div>&nb=
sp; }<br>};</div><div><br></div><div>std::sort(begin, end, __some_in=
ternal_type());</div><div><br></div><div>In order to preserve legacy code, =
a conversion to function pointers of an appropriate type must of course be =
specified.</div></blockquote><div><br>So, what happens to this code?<br><br=
><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); =
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; w=
ord-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyp=
rint"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">SomeFunc</span><span style=
=3D"color: #660;" 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">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettif=
y">GetFunctor</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><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 st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">function</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">SomeFunc</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">SomeFunc</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};}</span></div></code></div=
><br>In C++11, decltype(SomeFunc) is a <i>function</i> type, and is therefo=
re legal as a parameter to std::function. In your proposed revision, it isn=
't; it's an object type. Which cannot be the type provided to a std::functi=
on.<br><br>This should be an opt-in mechanism, not a magical "everything th=
at used to work one way works <i>completely</i> differently now thing. If y=
ou want it, you should have to ask for it in the declaration, using syntax =
like so:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #606;" class=3D"styled-by-prettify">ThisIsAFunc=
tion</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: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #606;" class=3D"styled-by-prettify">ThisIsAFunctor</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> functor</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">;</span></div></code></div><br>At whic=
h point, you don't have to deal with decaying to function pointers (though =
it could be allowed for non-template functors) or even the forwarding stuff=
anymore. We understand that `ThisIsAFunctor` declares an empty POD class t=
ype which has an overloaded `operator()` with the contents you provide. A g=
lobal variable called `ThisIsAFunctor` will be instantiated, which is admit=
tedly going to take some <i>very</i> creative wording to pull off, since yo=
u now have to deal with what happens when you stick one of these in a heade=
r. Is it externed everywhere? So which translation unit defines it?<br><br>=
There would be no function overloading as well, which is another thing that=
confounds your idea, since overloading is something that can happen in dif=
ferent translation units in different ways (different TLs can see different=
sets of functions with the same name). Type definitions can't be spread ac=
ross translation units, so if you wanted to group them all in a type defini=
tion, you'd have a problem.<br><br>`functor` would be one of those "context=
ual identifier" things like "final" and "override". So we wouldn't even nee=
d a keyword.<br> </div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv>It would be quite possible to do something similar with a polymorphic la=
mbda, except that the lambda would have to be repeatedly implemented at eve=
ry call site with all the boilerplate that involves. For a member, this wou=
ld look more like</div><div><br></div><div>struct X {</div><div> &nbs=
p; template<typename T> bool less(T lhs, T rhs) { return lhs < rhs=
; }<br></div><div>};</div><div>std::sort(begin, end, (expression that yield=
s an lvalue or rvalue x).less);</div><div><br></div><div>For a pointer to X=
, then</div><div><br></div><div>std::sort(begin, end, (expression that yiel=
ds an X*)->less);</div><div><br></div><div>For another example, if propo=
sals to allow type deduction on non-lambdas are accepted, it would now be p=
ossible to write a freestanding function which can be chained indefinitely.=
</div><div><br></div><div>auto f(int i) {</div><div> std::cout=
<< i;</div><div> return f;</div><div>}</div><div>int ma=
in() {</div><div> f(5)(5)(5)(5)(5)(5)(5); // arbitrary</div><d=
iv>}</div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><b=
r></div><div>These proposed changes would significantly simplify the use of=
functions as function parameters and bring their usability up to a par wit=
h function objects.</div></blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1436_21423219.1353632985994--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 22 Nov 2012 17:24:52 -0800 (PST)
Raw View
------=_Part_1839_16599246.1353633892645
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
Partly, I'd suggest that not permitting elision to work through perfect=20
forwarding is a problem, and I think the rules for elision should be=20
relaxed. However, there's plenty of precedent for compiler-generated=20
special functions not having to obey the same rules- for example, new T()=
=20
does not involve a move, it's constructed in place, and there's no reason=
=20
why similar wording cannot be applied here. In fact, you could argue that=
=20
this would be an extra justification for permitting such a proposal.
There would be no function overloading as well, which is another thing that=
=20
> confounds your idea, since overloading is something that can happen in=20
> different translation units in different ways (different TLs can see=20
> different sets of functions with the same name). Type definitions can't b=
e=20
> spread across translation units, so if you wanted to group them all in a=
=20
> type definition, you'd have a problem.
No (although this is my explanation fail). The entire point is to simplify=
=20
the use of overloaded functions which currently require explicit casts and=
=20
whatnot (as well as templates). After all, if I wrote the struct definition=
=20
out manually, the compiler still has to deal with that. When you use the=20
function object, it has the same effect as calling the function with those=
=20
arguments *at that exact place in that exact TU.* If that necessitates=20
creating multiple types for multiple usage points, then that's what's=20
necessary- and exactly what would happen if you used a lambda instead.
In C++11, decltype(SomeFunc) is a function type, and is therefore legal as=
=20
> a parameter to std::function. In your proposed revision, it isn't; it's a=
n=20
> object type. Which cannot be the type provided to a std::function.
I had considered suggesting an implicit conversion to solve this problem,=
=20
but I had forgotten about what would happen if you attempted to decltype=20
it. In principle, Special Language Wording=99 could intervene and suggest=
=20
that instead, it yields a function type (for example, a special instance of=
=20
my other proposal about automatic type conversions), but it would be much=
=20
simpler to simply suggest that the new wording would only apply where the=
=20
expression is not currently a valid function- for example, where the name=
=20
is an overloaded function or a template function without parameters.=20
Secondly, this would not prevent the use for member functions, which I feel=
=20
is just as, if not more, important than free functions.
--=20
------=_Part_1839_16599246.1353633892645
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
Partly, I'd suggest that not permitting elision to work through perfect for=
warding is a problem, and I think the rules for elision should be relaxed. =
However, there's plenty of precedent for compiler-generated special functio=
ns not having to obey the same rules- for example, new T() does not involve=
a move, it's constructed in place, and there's no reason why similar wordi=
ng cannot be applied here. In fact, you could argue that this would be an e=
xtra justification for permitting such a proposal.<div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left-wid=
th: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; p=
adding-left: 1ex;">There would be no function overloading as well, which is=
another thing that confounds your idea, since overloading is something tha=
t can happen in different translation units in different ways (different TL=
s can see different sets of functions with the same name). Type definitions=
can't be spread across translation units, so if you wanted to group them a=
ll in a type definition, you'd have a problem.</blockquote><div><br></div><=
div>No (although this is my explanation fail). The entire point is to simpl=
ify the use of overloaded functions which currently require explicit casts =
and whatnot (as well as templates). After all, if I wrote the struct defini=
tion out manually, the compiler still has to deal with that. When you use t=
he function object, it has the same effect as calling the function with tho=
se arguments <i>at that exact place in that exact TU.</i> If that nece=
ssitates creating multiple types for multiple usage points, then that's wha=
t's necessary- and exactly what would happen if you used a lambda instead.<=
/div><div><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;">In C++11, decltype(SomeFun=
c) is a function type, and is therefore legal as a parameter to std::functi=
on. In your proposed revision, it isn't; it's an object type. Which cannot =
be the type provided to a std::function.</blockquote><br>I had considered s=
uggesting an implicit conversion to solve this problem, but I had forgotten=
about what would happen if you attempted to decltype it. In principle, Spe=
cial Language Wording=99 could intervene and suggest that instead, it yield=
s a function type (for example, a special instance of my other proposal abo=
ut automatic type conversions), but it would be much simpler to simply sugg=
est that the new wording would only apply where the expression is not curre=
ntly a valid function- for example, where the name is an overloaded functio=
n or a template function without parameters. Secondly, this would not preve=
nt the use for member functions, which I feel is just as, if not more, impo=
rtant than free functions.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1839_16599246.1353633892645--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Thu, 22 Nov 2012 17:45:20 -0800 (PST)
Raw View
------=_Part_1126_33044812.1353635120812
Content-Type: text/plain; charset=ISO-8859-1
In addition, I'd like to ask you to consider not just a simplification
perspective, but also a maintenance one. Currently, given
bool f(int lhs, int rhs) { return lhs < rhs; }
std::sort(begin, end, f);
This is conforming code (assuming the required context for calling
std::sort). But if I add another overload of f, even one which is
completely irrelevant, it breaks.
bool f(int lhs, int rhs) { return lhs < rhs; }
bool f(std::string lhs, std::string rhs) { return lhs < rhs; }
std::sort(begin, end, f); // Illegal
In addition, you need to change the call site depending on whether you want
to choose an overload, or use an instantiation, of f.
If a proposal similar to this one were accepted, this code would now be
legal- that is, you can use the same code regardless of the overloads or
templates, of f, unless for some reason you need to explicitly pick one
(e.g. because ambiguities).
--
------=_Part_1126_33044812.1353635120812
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
In addition, I'd like to ask you to consider not just a simplification pers=
pective, but also a maintenance one. Currently, given<div><br></div><div>bo=
ol f(int lhs, int rhs) { return lhs < rhs; }</div><div>std::sort(begin, =
end, f);</div><div><br></div><div>This is conforming code (assuming the req=
uired context for calling std::sort). But if I add another overload of f, e=
ven one which is completely irrelevant, it breaks.</div><div><br></div><div=
><div>bool f(int lhs, int rhs) { return lhs < rhs; }</div><div>bool f(st=
d::string lhs, std::string rhs) { return lhs < rhs; }</div><div>std::sor=
t(begin, end, f); // Illegal</div></div><div><br></div><div>In addition, yo=
u need to change the call site depending on whether you want to choose an o=
verload, or use an instantiation, of f.</div><div><br></div><div>If a propo=
sal similar to this one were accepted, this code would now be legal- that i=
s, you can use the same code regardless of the overloads or templates, of f=
, unless for some reason you need to explicitly pick one (e.g. because ambi=
guities).</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1126_33044812.1353635120812--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 22 Nov 2012 19:00:30 -0800 (PST)
Raw View
------=_Part_67_25129245.1353639630460
Content-Type: text/plain; charset=ISO-8859-1
On Thursday, November 22, 2012 5:24:52 PM UTC-8, DeadMG wrote:
>
> Partly, I'd suggest that not permitting elision to work through perfect
> forwarding is a problem, and I think the rules for elision should be
> relaxed.
That's pretty much not possible. Elision works because of a contract
between the callee and the caller<http://stackoverflow.com/questions/6009278/why-are-by-value-parameters-excluded-from-nrvo/9595610#9595610>,
defined by the function signature. In order to do its part in elision, the
callee doesn't need to know more about what the caller does than the
signature. Similarly, all the caller knows is that it's been given some
memory; it doesn't care if something was copied into that memory or not.
In a 3-part system (callee, forwarder, and caller), everyone is blind to
everyone else. The callee can only see the signature of the forwarder. It
cannot *assume* that the forwarder is a forwarder at all. It knows nothing
about what the forwarder is going to do, so it must assume that the
forwarder will do what it's call signature says it will do. If it asks for
a reference, it gets a reference.
The forwarder gets a reference, not a value. So when it calls a function
that takes a value, it has no means of passing that reference through. It
must copy it, because the function takes a value that it expects to be a
unique value of that type, shared with nobody else. The forwarder can't
know that the callee created a temporary that won't be used beyond this
parameter. There is no special kind of "forwarding reference" to guarantee
that (no matter how much Scott Meyer wants there to be one). And without
that guarantee, the forwarder cannot do its part to create elision.
In fact, you could argue that this would be an extra justification for
> permitting such a proposal.
>
> There would be no function overloading as well, which is another thing
>> that confounds your idea, since overloading is something that can happen in
>> different translation units in different ways (different TLs can see
>> different sets of functions with the same name). Type definitions can't be
>> spread across translation units, so if you wanted to group them all in a
>> type definition, you'd have a problem.
>
>
> No (although this is my explanation fail). The entire point is to simplify
> the use of overloaded functions which currently require explicit casts and
> whatnot (as well as templates). After all, if I wrote the struct definition
> out manually, the compiler still has to deal with that. When you use the
> function object, it has the same effect as calling the function with those
> arguments *at that exact place in that exact TU.* If that necessitates
> creating multiple types for multiple usage points, then that's what's
> necessary- and exactly what would happen if you used a lambda instead.
>
You're not talking about a small compiler thing anymore. Now the compiler
needs to create new *type* every time the function is used (or at least,
frequently). This is not a tweak or a minor change; this is a fundamental
rewrite of some of the most basic parts of every compiler. Not to mention
the sheer amount of wording changing that needs to happen in the standard
to explain how this all works.
Basically all of chapter 13 would need to be massively reworked and
rewritten.
This is a *highly dangerous* thing you're suggesting, which can massively
break C++ in unpleasant and difficulty to detect ways. I'm not saying you
shouldn't pursue it, but you're talking about a feature who's complexity
demands a full study-group investigating it. Not to mention how it might
interact with the work of other study-groups, like reflection (which is
probably expecting functions to be actual functions and for individual
overloads to be counted like individual overloads), concepts, and the like.
Considering that you're already working on the Unicode proposal and you
mentioned something about an alternate iostreams idea, it may be too much
for you to develop.
--
------=_Part_67_25129245.1353639630460
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
On Thursday, November 22, 2012 5:24:52 PM UTC-8, DeadMG wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;">Partly, I'd suggest that not permitting eli=
sion to work through perfect forwarding is a problem, and I think the rules=
for elision should be relaxed.</blockquote><div><br>That's pretty much not=
possible. Elision works <a href=3D"http://stackoverflow.com/questions/6009=
278/why-are-by-value-parameters-excluded-from-nrvo/9595610#9595610">because=
of a contract between the callee and the caller</a>, defined by the functi=
on signature. In order to do its part in elision, the callee doesn't need t=
o know more about what the caller does than the signature. Similarly, all t=
he caller knows is that it's been given some memory; it doesn't care if som=
ething was copied into that memory or not.<br><br>In a 3-part system (calle=
e, forwarder, and caller), everyone is blind to everyone else. The callee c=
an only see the signature of the forwarder. It cannot <i>assume</i> that th=
e forwarder is a forwarder at all. It knows nothing about what the forwarde=
r is going to do, so it must assume that the forwarder will do what it's ca=
ll signature says it will do. If it asks for a reference, it gets a referen=
ce.<br><br>The forwarder gets a reference, not a value. So when it calls a =
function that takes a value, it has no means of passing that reference thro=
ugh. It must copy it, because the function takes a value that it expects to=
be a unique value of that type, shared with nobody else. The forwarder can=
't know that the callee created a temporary that won't be used beyond this =
parameter. There is no special kind of "forwarding reference" to guarantee =
that (no matter how much Scott Meyer wants there to be one). And without th=
at guarantee, the forwarder cannot do its part to create elision.<br><br></=
div><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">In fact, you could arg=
ue that this would be an extra justification for permitting such a proposal=
..<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-le=
ft-style:solid;padding-left:1ex">There would be no function overloading as =
well, which is another thing that confounds your idea, since overloading is=
something that can happen in different translation units in different ways=
(different TLs can see different sets of functions with the same name). Ty=
pe definitions can't be spread across translation units, so if you wanted t=
o group them all in a type definition, you'd have a problem.</blockquote><d=
iv><br></div><div>No (although this is my explanation fail). The entire poi=
nt is to simplify the use of overloaded functions which currently require e=
xplicit casts and whatnot (as well as templates). After all, if I wrote the=
struct definition out manually, the compiler still has to deal with that. =
When you use the function object, it has the same effect as calling the fun=
ction with those arguments <i>at that exact place in that exact TU.</i>&nbs=
p;If that necessitates creating multiple types for multiple usage points, t=
hen that's what's necessary- and exactly what would happen if you used a la=
mbda instead.</div></blockquote><div><br>You're not talking about a small c=
ompiler thing anymore. Now the compiler needs to create new <i>type</i> eve=
ry time the function is used (or at least, frequently). This is not a tweak=
or a minor change; this is a fundamental rewrite of some of the most basic=
parts of every compiler. Not to mention the sheer amount of wording changi=
ng that needs to happen in the standard to explain how this all works.<br><=
br>Basically all of chapter 13 would need to be massively reworked and rewr=
itten.<br><br>This is a <i>highly dangerous</i> thing you're suggesting, wh=
ich can massively break C++ in unpleasant and difficulty to detect ways. I'=
m not saying you shouldn't pursue it, but you're talking about a feature wh=
o's complexity demands a full study-group investigating it. Not to mention =
how it might interact with the work of other study-groups, like reflection =
(which is probably expecting functions to be actual functions and for indiv=
idual overloads to be counted like individual overloads), concepts, and the=
like.<br><br>Considering that you're already working on the Unicode propos=
al and you mentioned something about an alternate iostreams idea, it may be=
too much for you to develop.<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_67_25129245.1353639630460--
.
Author: grigorij1981@gmail.com
Date: Fri, 23 Nov 2012 00:14:46 -0800 (PST)
Raw View
------=_Part_72_19623448.1353658486635
Content-Type: text/plain; charset=ISO-8859-1
A year ago in cpp-next thread<http://cpp-next.com/archive/2011/11/having-it-all-pythy-syntax/#q-1732>Giovanni Deretta proposed a new syntax for passing functions to
higher-order functions:
hof([]min, 0, 1);
where []*id-expression* is a way of capturing an overload set. I haven't seen any further development of that idea, but it seems like a really nice way to simplify usage of functions as function parameters without fundamental changes.
Regards,
Gregory
--
------=_Part_72_19623448.1353658486635
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div> </div><div> A year ago in cpp-next <a href=3D"http://cpp-ne=
xt.com/archive/2011/11/having-it-all-pythy-syntax/#q-1732">thread</a> Giova=
nni Deretta proposed a new syntax for passing functions to higher-order fun=
ctions:</div><div> </div><div><pre>hof([]min, 0, 1); </pre><pre> =
</pre><pre><font face=3D"arial,sans-serif">where []<em>id-expression</em> i=
s a way of capturing an overload set. I haven't seen any further developmen=
t of that idea, but it seems like a really nice way to simplify usage of fu=
nctions as function parameters without fundamental changes.</font></pre><pr=
e><font face=3D"Arial"></font> </pre><pre><font face=3D"Arial">Regards=
,</font></pre><pre><font face=3D"Arial">Gregory</font></pre></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_72_19623448.1353658486635--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 23 Nov 2012 00:54:36 -0800 (PST)
Raw View
------=_Part_1261_3386308.1353660876669
Content-Type: text/plain; charset=ISO-8859-1
Nah, I didn't get along with my university and am currently unemployed, so.
You're not talking about a small compiler thing anymore. Now the compiler
> needs to create new *type* every time the function is used (or at least,
> frequently). This is not a tweak or a minor change; this is a fundamental
> rewrite of some of the most basic parts of every compiler. Not to mention
> the sheer amount of wording changing that needs to happen in the standard
> to explain how this all works.
This is not a big deal at all. It's just a polymorphic lambda which has
been given a syntactic upgrade for maintainability. We already have
polymorphic lambdas, or should do. There's nothing different between
sort(begin, end, less)
and
sort(begin, end, []<class... T>(T&&... args) { return
less(std::forward<T>(args)...); });
You're asking the compiler to do the exact same amount of work, and
specifying them in pretty much exactly the same way (except polymorphic
lambdas are more general and thus require a lot more specifying).
This is a *highly dangerous* thing you're suggesting, which can massively
> break C++ in unpleasant and difficulty to detect ways.
Like what? I accept that changing it for functions which are not overloads
or templates would be nasty, but existing code which tries to do that is
quite ill-formed, and the proposed behaviour is easily specified and quite
safe.
--
------=_Part_1261_3386308.1353660876669
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Nah, I didn't get along with my university and am currently unemployed, so.=
<div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); bo=
rder-left-style: solid; padding-left: 1ex;">You're not talking about a smal=
l compiler thing anymore. Now the compiler needs to create new <i>type=
</i> every time the function is used (or at least, frequently). This i=
s not a tweak or a minor change; this is a fundamental rewrite of some of t=
he most basic parts of every compiler. Not to mention the sheer amount of w=
ording changing that needs to happen in the standard to explain how this al=
l works.</blockquote><div><br></div><div>This is not a big deal at all. It'=
s just a polymorphic lambda which has been given a syntactic upgrade for ma=
intainability. We already have polymorphic lambdas, or should do. There's n=
othing different between</div><div><br></div><div>sort(begin, end, less)</d=
iv><div><br></div><div>and</div><div><br></div><div>sort(begin, end, []<=
class... T>(T&&... args) { return less(std::forward<T>(arg=
s)...); });</div><div><br></div><div>You're asking the compiler to do the e=
xact same amount of work, and specifying them in pretty much exactly the sa=
me way (except polymorphic lambdas are more general and thus require a lot =
more specifying). </div><div><br></div><blockquote class=3D"gmail_quot=
e" 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;">Th=
is is a <i>highly dangerous</i> thing you're suggesting, which ca=
n massively break C++ in unpleasant and difficulty to detect ways.</blockqu=
ote><div><br></div><div>Like what? I accept that changing it for functions =
which are not overloads or templates would be nasty, but existing code whic=
h tries to do that is quite ill-formed, and the proposed behaviour is easil=
y specified and quite safe. </div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_1261_3386308.1353660876669--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 23 Nov 2012 01:18:29 -0800 (PST)
Raw View
------=_Part_19_9211394.1353662309347
Content-Type: text/plain; charset=ISO-8859-1
On Friday, November 23, 2012 12:54:36 AM UTC-8, DeadMG wrote:
>
> Nah, I didn't get along with my university and am currently unemployed, so.
>
> You're not talking about a small compiler thing anymore. Now the compiler
>> needs to create new *type* every time the function is used (or at least,
>> frequently). This is not a tweak or a minor change; this is a fundamental
>> rewrite of some of the most basic parts of every compiler. Not to mention
>> the sheer amount of wording changing that needs to happen in the standard
>> to explain how this all works.
>
>
> This is not a big deal at all. It's just a polymorphic lambda which has
> been given a syntactic upgrade for maintainability. We already have
> polymorphic lambdas, or should do. There's nothing different between
>
> sort(begin, end, less)
>
> and
>
> sort(begin, end, []<class... T>(T&&... args) { return
> less(std::forward<T>(args)...); });
>
> You're asking the compiler to do the exact same amount of work, and
> specifying them in pretty much exactly the same way (except polymorphic
> lambdas are more general and thus require a lot more specifying).
>
>
This is a *highly dangerous* thing you're suggesting, which can massively
>> break C++ in unpleasant and difficulty to detect ways.
>
>
> Like what? I accept that changing it for functions which are not overloads
> or templates would be nasty, but existing code which tries to do that is
> quite ill-formed, and the proposed behaviour is easily specified and quite
> safe.
>
You are talking about changing the *very meaning of what a function is*.
This will affect every function that calls another function. Code that
passed around function pointers of a known type now will suddenly start
passing around functors of unknown and unknowable types. "quite safe" is
not how I would describe *any* change with such far-reaching implications.
--
------=_Part_19_9211394.1353662309347
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<br><br>On Friday, November 23, 2012 12:54:36 AM UTC-8, DeadMG wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;">Nah, I didn't get along with my univ=
ersity and am currently unemployed, so.<div><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">You'=
re not talking about a small compiler thing anymore. Now the compiler needs=
to create new <i>type</i> every time the function is used (or at=
least, frequently). This is not a tweak or a minor change; this is a funda=
mental rewrite of some of the most basic parts of every compiler. Not to me=
ntion the sheer amount of wording changing that needs to happen in the stan=
dard to explain how this all works.</blockquote><div><br></div><div>This is=
not a big deal at all. It's just a polymorphic lambda which has been given=
a syntactic upgrade for maintainability. We already have polymorphic lambd=
as, or should do. There's nothing different between</div><div><br></div><di=
v>sort(begin, end, less)</div><div><br></div><div>and</div><div><br></div><=
div>sort(begin, end, []<class... T>(T&&... args) { return les=
s(std::forward<T>(args)...)<wbr>; });</div><div><br></div><div>You're=
asking the compiler to do the exact same amount of work, and specifying th=
em in pretty much exactly the same way (except polymorphic lambdas are more=
general and thus require a lot more specifying).<br> </div></blockquo=
te><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;b=
order-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"=
>This is a <i>highly dangerous</i> thing you're suggesting, which=
can massively break C++ in unpleasant and difficulty to detect ways.</bloc=
kquote><div><br></div><div>Like what? I accept that changing it for functio=
ns which are not overloads or templates would be nasty, but existing code w=
hich tries to do that is quite ill-formed, and the proposed behaviour is ea=
sily specified and quite safe. </div></blockquote><div><br>You are tal=
king about changing the <i>very meaning of what a function is</i>. This wil=
l affect every function that calls another function. Code that passed aroun=
d function pointers of a known type now will suddenly start passing around =
functors of unknown and unknowable types. "quite safe" is not how I would d=
escribe <i>any</i> change with such far-reaching implications.<br></div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_19_9211394.1353662309347--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 23 Nov 2012 01:59:30 -0800 (PST)
Raw View
------=_Part_41_8056270.1353664770158
Content-Type: text/plain; charset=ISO-8859-1
If the wording is changed to specify only overloaded or template functions,
then existing code will not have a single shred of meaning changed.
*very meaning of what a function is*.
Overloading, operator overloading and templates and lambdas changed that.
All I'm doing is passing it around as an object in a simple, convenient
package.
Again, all we're talking about is implicitly creating a very simple
polymorphic lambda. There's nothing more to it.
--
------=_Part_41_8056270.1353664770158
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
If the wording is changed to specify only overloaded or template functions,=
then existing code will not have a single shred of meaning changed.<div><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8e=
x; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-le=
ft-style: solid; padding-left: 1ex;"><i>very meaning of what a function is<=
/i>.</blockquote><div><br></div><div>Overloading, operator overloading and =
templates and lambdas changed that. All I'm doing is passing it around=
as an object in a simple, convenient package.</div><div><br></div><div>Aga=
in, all we're talking about is implicitly creating a very simple polymorphi=
c lambda. There's nothing more to it.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_41_8056270.1353664770158--
.
Author: Xeo <hivemaster@hotmail.de>
Date: Fri, 23 Nov 2012 06:15:22 -0800 (PST)
Raw View
------=_Part_27_25135009.1353680123003
Content-Type: text/plain; charset=ISO-8859-1
I was thinking of that exact same syntax (not having seen the cpp-next
thread). In my thinking, it would be simple syntactic sugar to lift a
function (set) to a function object.
With the polymorphic lambda proposal, it's implementable as a preprocessor
macro:
#define LIFT_FUN(name) [&]<class... Ts>(T&&... vs){ return name(std::forward
<Ts>(vs)...); }
with which you can write sort(f, l, LIFT_FUN(less)).
But as we all know, "macros are evil" and there are probably some subtle
pitfalls with the macro version, so I'd really like to see this added to
the standard:
sort(f, l, []less);
On Friday, November 23, 2012 9:14:46 AM UTC+1, grigor...@gmail.com wrote:
>
>
> A year ago in cpp-next thread<http://cpp-next.com/archive/2011/11/having-it-all-pythy-syntax/#q-1732>Giovanni Deretta proposed a new syntax for passing functions to
> higher-order functions:
>
>
> hof([]min, 0, 1);
>
>
>
> where []*id-expression* is a way of capturing an overload set. I haven't seen any further development of that idea, but it seems like a really nice way to simplify usage of functions as function parameters without fundamental changes.
>
>
>
> Regards,
>
> Gregory
>
>
--
------=_Part_27_25135009.1353680123003
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
I was thinking of that exact same syntax (not having seen the cpp-next thre=
ad). In my thinking, it would be simple syntactic sugar to lift a function =
(set) to a function object.<br><br>With the polymorphic lambda proposal, it=
's implementable as a preprocessor macro:<br><br><div class=3D"prettyprint"=
style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
187); border-style: solid; border-width: 1px; word-wrap: break-word;"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#800;" class=3D"styled-by-prettify">#define</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> LIFT_FUN</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">name</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: #008;" class=3D"styled-by-prettify"=
>class</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">Ts</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"c=
olor: #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;" class=3D"styled-by-prettify"> vs</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-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> name</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">forward</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Ts</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">vs</span><span style=3D"color: #660;" cla=
ss=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></div></code></div><br>with which you can write <span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><code></code>sort</span><sp=
an 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;" =
class=3D"styled-by-prettify"> l</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> LIFT_FUN</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">less</span><span style=3D"color: #660;" class=3D"styled-by-prettify">))</=
span><code class=3D"prettyprint"></code><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><code class=3D"prettyprint"></code><br>But as we =
all know, "macros are evil" and there are probably some subtle pitfalls wit=
h the macro version, so I'd really like to see this added to the standard:<=
br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">sort<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an 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"> l</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">less</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);=
</span></div></code></div><br>On Friday, November 23, 2012 9:14:46 AM UTC+1=
, grigor...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv> </div><div> A year ago in cpp-next <a href=3D"http://cpp-next=
..com/archive/2011/11/having-it-all-pythy-syntax/#q-1732" target=3D"_blank">=
thread</a> Giovanni Deretta proposed a new syntax for passing functions to =
higher-order functions:</div><div> </div><div><pre>hof([]min, 0, 1); <=
/pre><pre> </pre><pre><font face=3D"arial,sans-serif">where []<i>id-ex=
pression</i> is a way of capturing an overload set. I haven't seen any furt=
her development of that idea, but it seems like a really nice way to simpli=
fy usage of functions as function parameters without fundamental changes.</=
font></pre><pre><font face=3D"Arial"></font> </pre><pre><font face=3D"=
Arial">Regards,</font></pre><pre><font face=3D"Arial">Gregory</font></pre><=
/div></blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_27_25135009.1353680123003--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Fri, 23 Nov 2012 07:43:08 -0800 (PST)
Raw View
------=_Part_418_9178429.1353685388470
Content-Type: text/plain; charset=ISO-8859-1
ADL could present another problem. If you do
sort(f, l, less)
and there is no less in scope, even though it could be found by ADL, then
it would be ill-formed. The lambda version, however, would not be
ill-formed. So I think that there may not be a problem with []less, which
would be fine with ADL, and if you did something like auto p = []less, then
there's no confusion that you're getting a function object.
--
------=_Part_418_9178429.1353685388470
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
ADL could present another problem. If you do<div><br></div><div>sort(f, l, =
less) </div><div><br></div><div>and there is no less in scope, even th=
ough it could be found by ADL, then it would be ill-formed. The lambda vers=
ion, however, would not be ill-formed. So I think that there may not be a p=
roblem with []less, which would be fine with ADL, and if you did something =
like auto p =3D []less, then there's no confusion that you're getting a fun=
ction object.</div>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_418_9178429.1353685388470--
.
Author: grigorij1981@gmail.com
Date: Fri, 23 Nov 2012 00:30:13 -0800 (PST)
Raw View
------=_Part_19_5831689.1353659413420
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
By the way if we allow [] with operators then we would have a really=20
concise way of passing operators to functions, for example
=20
accumulate(v.begin(), v.end(), []*); // instead of multiply<>
=D0=9F=CA=BC=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D1=8F, 23 =D0=BB=D0=B8=D1=81=D1=
=82=D0=BE=D0=BF=D0=B0=D0=B4=D0=B0 2012 =D1=80. 10:14:46 UTC+2 =D0=BA=D0=BE=
=D1=80=D0=B8=D1=81=D1=82=D1=83=D0=B2=D0=B0=D1=87=20
grigor...@gmail.com =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=B2:
> =20
> A year ago in cpp-next thread<http://cpp-next.com/archive/2011/11/having=
-it-all-pythy-syntax/#q-1732>Giovanni Deretta proposed a new syntax for pas=
sing functions to=20
> higher-order functions:
> =20
>
> hof([]min, 0, 1);=20
>
> =20
>
> where []*id-expression* is a way of capturing an overload set. I haven't =
seen any further development of that idea, but it seems like a really nice =
way to simplify usage of functions as function parameters without fundament=
al changes.
>
> =20
>
> Regards,
>
> Gregory
>
>
--=20
------=_Part_19_5831689.1353659413420
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div>By the way if we allow [] with operators then we would have a really c=
oncise way of passing operators to functions, for example</div><div> <=
/div><div><font face=3D"courier new,monospace">accumulate(v.begin(), v.end(=
), []*); // instead of multiply<></font></div><div><br>=D0=9F=CA=BC=
=D1=8F=D1=82=D0=BD=D0=B8=D1=86=D1=8F, 23 =D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=
=BF=D0=B0=D0=B4=D0=B0 2012 =D1=80. 10:14:46 UTC+2 =D0=BA=D0=BE=D1=80=D0=B8=
=D1=81=D1=82=D1=83=D0=B2=D0=B0=D1=87 grigor...@gmail.com =D0=BD=D0=B0=D0=BF=
=D0=B8=D1=81=D0=B0=D0=B2:</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 20=
4, 204); border-left-width: 1px; border-left-style: solid;"><div> </di=
v><div> A year ago in cpp-next <a href=3D"http://cpp-next.com/archive/=
2011/11/having-it-all-pythy-syntax/#q-1732" target=3D"_blank">thread</a> Gi=
ovanni Deretta proposed a new syntax for passing functions to higher-order =
functions:</div><div> </div><div><pre>hof([]min, 0, 1); </pre><pre>&nb=
sp;</pre><pre><font face=3D"arial,sans-serif">where []<em>id-expression</em=
> is a way of capturing an overload set. I haven't seen any further develop=
ment of that idea, but it seems like a really nice way to simplify usage of=
functions as function parameters without fundamental changes.</font></pre>=
<pre><font face=3D"Arial"></font> </pre><pre><font face=3D"Arial">Rega=
rds,</font></pre><pre><font face=3D"Arial">Gregory</font></pre></div></bloc=
kquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_19_5831689.1353659413420--
.
Author: DeadMG <wolfeinstein@gmail.com>
Date: Sat, 24 Nov 2012 03:00:13 -0800 (PST)
Raw View
------=_Part_43_6543613.1353754813679
Content-Type: text/plain; charset=ISO-8859-1
You would need an object on which to call operator() anyway, so []() as in
"Lifted operator()" doesn't really make sense.
--
------=_Part_43_6543613.1353754813679
Content-Type: text/html; charset=ISO-8859-1
You would need an object on which to call operator() anyway, so []() as in "Lifted operator()" doesn't really make sense.
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_43_6543613.1353754813679--
.
Author: grigorij1981@gmail.com
Date: Sat, 24 Nov 2012 04:29:20 -0800 (PST)
Raw View
------=_Part_271_28739106.1353760160729
Content-Type: text/plain; charset=KOI8-U
Content-Transfer-Encoding: quoted-printable
I was not clear. In the same thread<http://cpp-next.com/archive/2011/11/hav=
ing-it-all-pythy-syntax/#q-1755>Giovanni Deretta proposed unification of me=
mber-functions and=20
free-functions for []*function *syntax.
=20
*Regarding the []<class>::<member> syntax, after thinking about it more, it=
=20
should be probably folded in the general []id-expression; syntax. I.e:*
*([]id-expression)(x);*
*should map to the first compilable of the following *
*x.id-expression;
x.id-expression();
id-expression(x);*
**=20
So, my remark was in the context of that proposal. If it would be possible =
then []() would be analogous to boost::apply<>.
=20
=20
=F3=D5=C2=CF=D4=C1, 24 =CC=C9=D3=D4=CF=D0=C1=C4=C1 2012 =D2. 13:00:13 UTC+2=
=CB=CF=D2=C9=D3=D4=D5=D7=C1=DE DeadMG =CE=C1=D0=C9=D3=C1=D7:
> You would need an object on which to call operator() anyway, so []() as i=
n=20
> "Lifted operator()" doesn't really make sense.
--=20
------=_Part_271_28739106.1353760160729
Content-Type: text/html; charset=KOI8-U
Content-Transfer-Encoding: quoted-printable
<div>I was not clear. In the same <a href=3D"http://cpp-next.com/archive/20=
11/11/having-it-all-pythy-syntax/#q-1755">thread</a> Giovanni Deretta propo=
sed unification of member-functions and free-functions for []<em>function <=
/em>syntax.</div><div> </div><div><p><em>Regarding the []<class>=
::<member> syntax, after thinking about it more, it should be probabl=
y folded in the general []id-expression; syntax. I.e:</em></p><pre><em>([]i=
d-expression)(x);</em></pre><em>should map to the first compilable of the f=
ollowing </em><pre><em>x.id-expression;
x.id-expression();
id-expression(x);</em></pre><pre><em></em> </pre><pre><font face=3D"ar=
ial,sans-serif">So, my remark was in the context of that proposal. If it wo=
uld be possible then []() would be analogous to boost::apply<>.</font=
></pre><pre><font face=3D"Arial"></font> </pre><pre><font face=3D"Aria=
l"></font> </pre></div><div><br>=F3=D5=C2=CF=D4=C1, 24 =CC=C9=D3=D4=CF=
=D0=C1=C4=C1 2012 =D2. 13:00:13 UTC+2 =CB=CF=D2=C9=D3=D4=D5=D7=C1=DE DeadMG=
=CE=C1=D0=C9=D3=C1=D7:</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204,=
204); border-left-width: 1px; border-left-style: solid;">You would need an=
object on which to call operator() anyway, so []() as in "Lifted operator(=
)" doesn't really make sense.</blockquote>
<p></p>
-- <br />
<br />
<br />
<br />
------=_Part_271_28739106.1353760160729--
.
Author: Alex B <devalexb@gmail.com>
Date: Thu, 31 Jan 2013 21:19:59 -0800 (PST)
Raw View
------=_Part_477_26444911.1359695999646
Content-Type: text/plain; charset=ISO-8859-1
I think the intent of the original proposal is quite justified; it would be
really nice to have a simpler way of passing/returning a function call with
(yet) unresolved overloads.
However, I do agree with other writers that going "all-in" and making
everything become a function object is quite abusive. The proposed use of
an explicit []*id-expression* syntax is a very interesting idea.
How about going the implicit way (like in the original proposal) *but only
when needed*? I mean a function object could be implicitly created like in
the original proposal, *but only when an overload could not be resolved*.
So current function pointers would be kept as function pointers, and only
specific cases which are not compiling with the current standard (because
of overload resolution) would now compile by implicitly generating what I
would call an "implicit polymorphic function object".
Also, in the original post, I see a second proposal (was it intended?)
which was not discussed so far and should be considered on its own:
std::sort(begin, end, (expression that yields an lvalue or rvalue x).less);
std::sort(begin, end, (expression that yields an X*)->less);
>
Here, I interpret it as automatically generating a function object by
binding a member function with an object on which to invoke it. I think it
is a very interesting idea (that was maybe raised somewhere else).
--
---
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/?hl=en.
------=_Part_477_26444911.1359695999646
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
I think the intent of the original proposal is quite justified; it would be=
really nice to have a simpler way of passing/returning a function call wit=
h (yet) unresolved overloads.<br>However, I do agree with other writers tha=
t going "all-in" and making everything become a function object is quite ab=
usive. The proposed use of an explicit <span style=3D"font-family: ari=
al, sans-serif;">[]</span><em style=3D"font-family: arial, sans-serif;">id-=
expression</em> syntax is a very interesting idea.<br><div><br></div><=
div>How about going the implicit way (like in the original proposal) <b>but=
only when needed</b>? I mean a function object could be implicitly created=
like in the original proposal, <i>but only when an overload could not be r=
esolved</i>. So current function pointers would be kept as function pointer=
s, and only specific cases which are not compiling with the current standar=
d (because of overload resolution) would now compile by implicitly&nbs=
p;generating what I would call an "implicit polymorphic function object".</=
div><div><br></div><div>Also, in the original post, I see a second proposal=
(was it intended?) which was not discussed so far and should be considered=
on its own:</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=
;">std::sort(begin, end, (expression that yields an lvalue or rvalue x).les=
s);</blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>std::sort=
(begin, end, (expression that yields an X*)->less);</div></blockquote><d=
iv><br></div><div>Here, I interpret it as automatically generating a functi=
on object by binding a member function with an object on which to invoke it=
.. I think it is a very interesting idea (that was maybe raised somewhere el=
se).</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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
<br />
<br />
------=_Part_477_26444911.1359695999646--
.