220 5528 <e41b791b-eaa1-4156-9116-f2f7036ae4ae@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Xeo <hivemaster@hotmail.de>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Grouping placeholders for bind
Date: Tue, 23 Jul 2013 14:22:39 -0700 (PDT)
Lines: 285
Approved: news@gmane.org
Message-ID: <e41b791b-eaa1-4156-9116-f2f7036ae4ae@isocpp.org>
References: <81385547-bb12-4ae6-9d12-82aaeb4b5ba0@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_847_7630750.1374614559631"
X-Trace: ger.gmane.org 1374614560 4019 80.91.229.3 (23 Jul 2013 21:22:40 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Tue, 23 Jul 2013 21:22:40 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCCNBYNYXMJRBIHIXOHQKGQEDRWBVNY@isocpp.org Tue Jul 23 23:22:43 2013
Return-path: <std-proposals+bncBCCNBYNYXMJRBIHIXOHQKGQEDRWBVNY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-gg0-f200.google.com ([209.85.161.200])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCCNBYNYXMJRBIHIXOHQKGQEDRWBVNY@isocpp.org>)
	id 1V1k2b-00053K-LL
	for gclcip-std-proposals@m.gmane.org; Tue, 23 Jul 2013 23:22:41 +0200
Original-Received: by mail-gg0-f200.google.com with SMTP id k5sf8838915ggd.3
        for <gclcip-std-proposals@m.gmane.org>; Tue, 23 Jul 2013 14:22:40 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=google.com; s=20120113;
        h=x-beenthere:date:from:to:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:x-google-group-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=N0NbhchBIw9Qw3ZwvmjQNE8sQPT5PJb1yJgJyrHZYeQ=;
        b=GufqvmZCUdVrC00bC+CGl9AfAI3VH6vIO6advReoYFcGymT4Pw127rim2/M85Yz50R
         B/d41QJYcPrC+LYKYCF0FFilgjrYdx3gLpgc9Xnx2SL6QNrEu0OAF7o6ZNEpnxW6VLFe
         Yv0nyQTSgY85jfJNJD0KAv65CYhChErzxEUPcXuFP27xB/sNQRV78G95zYKJh2g5EkJB
         KSI8hxgU1RGdGlrbUzqIbhkr/m/aZLiAw+gmRpjF4A4/LbwmZmYQLJ06GjJiY4PWF3cJ
         kM9gHnz+y6+z6+vYUSEtA+hu6w1RgQa1nDIQyTa/hq2iOivGiByGabXhIjLrrCIKYzTZ
         WbHg==
X-Received: by 10.236.137.35 with SMTP id x23mr19943906yhi.7.1374614560758;
        Tue, 23 Jul 2013 14:22:40 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.50.10 with SMTP id y10ls3187130qen.69.gmail; Tue, 23 Jul
 2013 14:22:40 -0700 (PDT)
X-Received: by 10.49.82.50 with SMTP id f18mr1330113qey.22.1374614560065;
        Tue, 23 Jul 2013 14:22:40 -0700 (PDT)
In-Reply-To: <81385547-bb12-4ae6-9d12-82aaeb4b5ba0@isocpp.org>
X-Original-Sender: hivemaster@hotmail.de
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:5528
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/5528>

------=_Part_847_7630750.1374614559631
Content-Type: text/plain; charset=ISO-8859-1

I have played around with implementing such an `easy_bind` (as I call it) 
before, which can be found here <http://stackoverflow.com/a/15025170/500104>and is really easy (especially in C++14 when you can just use 
`decltype(auto)` for the return type).

You will notice that I used `std::function<R(FArgs...)>` instead of a 
generic `class F` in the public interface - the reason is that not all 
function objects can have the number of their parameters determined. The 
`operator()` may be either overloaded, templated, or both, rendering any 
attempt to get a specific signature moot.

Of course, the overhead (if actually there) of `std::function` is likely 
unwanted in such a general purpose function. However, there are really only 
two callable entities where the signature can be inspected: 
function-pointers and member-function-pointers. As such, with the interface 
of `std::bind` today, you can't really do better than that.

The second argument N would mean actual number of argument provided to 
> invocation of the bind (so we cane genereate index of all arguments)
>
Here is the problem. First, the number of (bound) arguments passed to 
`std::bind` is irrelevant for the placeholders that are needed; these need, 
if anything, to be determined from the passed callable object. Second, 
notice that Jonathan specifically did *not* mention any indices. This 
`std::placeholders::all` form requires a very different implementation that 
simply forwards all arguments that are passed at the invocation of the 
returned bind object. It cannot be done with the current interface and 
numbered placeholders, simply because some functions don't even *have* an 
upper bound on the number of arguments - variadic templates say hello.

On Tuesday, July 23, 2013 10:40:57 PM UTC+2, toma...@gmail.com wrote:
>
> In the discussion of mem_fn with additional parameter<https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/CxpGVY1APcs> Jonathan 
> Wakely proposed the idea of new placeholder type named all,
>  that will forward all of the arguments to the functor and suggested that 
> it could be extended to more generic group placeholders.
> Example:
> auto f = std::bind(&A::foo, a, std::placeholders::all);
> Will create functor that will bind an object/pointer a with the function 
> member pointer and forwards all supplied arguments to the functor, 
> so:
> f(t1, t2, ..., tN)
> Will be equivalent to:
> a.foo(t1, t2, ..., tN) 
> //I assumed a is an object in the example, but it will support anything 
> that INVOKE does.
>
> I would like to share my thoughts on the approach how such placeholders 
> can be defined in the extend-able manner (so the user can define
> its own group placeholders).
>
> 1. At this moment the standard defines the is_placeholder traits that 
> provides both functionality: informs that the type placeholder and provides 
> the number of forwarder argument. I would like to split that behavior, to 
> 2 classes:
>   a) is_placeholder<T> would be used to determine if the type is 
> placeholder
>   b) placeholder_positions<T,N> will provide zero (please see motivation 
> bellow) or more index of argument to be forwarder (index should be 1based to
>       uniform with standard bind). The second argument N would mean actual 
> number of argument provided to invocation of the bind (so we cane genereate
>       index of all arguments). The placeholder position should be derived 
> from std::integer_sequence<std::size_t, ...> class in case when 
> is_placeholder<T>::value
>     is true.
>   c) to main the backward compatibility the, default implementation of placeholder_positions 
> would be:
>     template<typename T, std::size_t N>
>     struct placeholder_positions :
>        std::integer_sequence<std::size_t, std::is_placeholder<T>::value>
>     {}
>       so for the single argument placeholder, is_placeholder can be used 
> in the same way as today, but bind depend only for  placeholder_positions
>   to get argument  to forward.
>
> 2. There should be 2 group placeholders defined in the standard:
>     a) _all, that will forward all arguments, definition using proposed 
> specializations would be:
>        template<>
>    struct is_placeholder<_all> : std::true_type {};
>
>    template<std::size_t N>
>    struct placeholder_positions<_all, N>
>      : shift<std::make_integer_sequence<std::size_t, N>, 1> {} 
>   b)  _from<N> that will forward arguments all arguments form Nth. The 
> _from<N> should be ill formed if number of arguments is less than N. For 
> exactly N-1
>         arguments there should be empty sequence generated - if there is 
> need to be sure that at least N arguments, then _N, _from<N+1> may be used.
>        Implementation:
>        template<std::size_t N>
>    struct is_placeholder<_from<N>> : std::true_type {};
>    
>    template<std::size_t N>
>    struct placeholder_positions<_all, ArgCount>
>      : enable_if<ArgCount + 1 <= N,      
>                  shift<std::make_integer_sequence<std::size_t, ArgCount - 
> N  + 1>, N> {}
>   c) The user can define its own placeholders group via specializations.
>
> 3. I would define new placeholder in the namespace std::placeholders, but 
> that may lead to the some annoying problems to the user if there where 
> named simply
>     all and from. Most of the code that uses bind, looks like:
>     using namespace std::placeholders;
>     std::bind(f, _1, a, _2);
>     While there is really low possibility to have variables named _1, _2, 
> ... in the user code, there is pretty much a chance that the user code 
> would define viarbles
>     named all or from and cause the crash of bind.  That it the reason I 
> choosed _all and _from instead, which look pretty uniform with _1. Another 
> solution would be
>     to define it in the different namespace.
>
> What are you thoughts about this idea.
>

-- 

--- 
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_847_7630750.1374614559631
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I have played around with implementing such an `easy_bind` (as I call it) b=
efore, which can be found <a href=3D"http://stackoverflow.com/a/15025170/50=
0104">here</a> and is really easy (especially in C++14 when you can just us=
e `decltype(auto)` for the return type).<br><br>You
 will notice that I used `std::function&lt;R(FArgs...)&gt;` instead of a
 generic `class F` in the public interface - the reason is that not all=20
function objects can have the number of their parameters determined. The
 `operator()` may be either overloaded, templated, or both, rendering=20
any attempt to get a specific signature moot.<br><br>Of course, the=20
overhead (if actually there) of `std::function` is likely unwanted in=20
such a general purpose function. However, there are really only two callabl=
e entities where the signature can be inspected:=20
function-pointers and member-function-pointers. As such, with the interface=
 of `std::bind` today, you can't really do better than that.<br><br><blockq=
uote style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, 20=
4, 204); padding-left: 1ex;" class=3D"gmail_quote"><span><span style=3D"col=
or:rgb(34,34,34)">The second argument N would mean actual number of argumen=
t provided to invocation of the bind (so we cane genereate index of all arg=
uments)</span></span><br></blockquote><div>Here is the problem. First, the =
number of (bound) arguments passed to `std::bind` is irrelevant for the pla=
ceholders that are needed; these need, if anything, to be determined from t=
he passed callable object. Second, notice that Jonathan specifically did <i=
>not</i> mention any indices. This `std::placeholders::all` form requires a=
 very different implementation that simply forwards all arguments that are =
passed at the invocation of the returned bind object. It cannot be done wit=
h the current interface and numbered placeholders, simply because some func=
tions don't even *have* an upper bound on the number of arguments - variadi=
c templates say hello.<br></div><br>On Tuesday, July 23, 2013 10:40:57 PM U=
TC+2, toma...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
In the discussion of <a href=3D"https://groups.google.com/a/isocpp.org/foru=
m/?fromgroups#!topic/std-proposals/CxpGVY1APcs" target=3D"_blank">mem_fn wi=
th additional parameter</a> <span><span style=3D"color:rgb(34,34,34)">Jonat=
han Wakely proposed the idea of new placeholder type named all,<br>&nbsp;th=
at will forward all of the arguments to the functor and suggested that it c=
ould be extended to more generic group placeholders.<br>Example:<br><span s=
tyle=3D"font-family:courier new,monospace">auto f =3D std::bind(&amp;A::foo=
, a, std::placeholders::all);</span><br>Will create functor that will bind =
an object/pointer a with the function member pointer and forwards all suppl=
ied arguments to the functor, <br>so:<br><span style=3D"font-family:courier=
 new,monospace">f(t1, t2, ..., tN)</span><br>Will be equivalent to:<br><spa=
n style=3D"font-family:courier new,monospace">a.foo</span></span></span><sp=
an><span style=3D"color:rgb(34,34,34)"><span style=3D"font-family:courier n=
ew,monospace">(t1, t2, ..., tN) </span><br>//I assumed a is an object in th=
e example, but it will support anything that INVOKE does.<br><br>I would li=
ke to share my thoughts on the approach how such placeholders can be define=
d in the extend-able manner (so the user can define<br>its own group placeh=
olders).<br><br>1. At this moment the standard defines the is_placeholder t=
raits that provides both functionality: informs that the type placeholder a=
nd provides <br>the number of forwarder argument. I would like to split tha=
t behavior, to 2 classes:<br>&nbsp; a) is_placeholder&lt;T&gt; would be use=
d to determine if the type is placeholder<br>&nbsp; b) placeholder_position=
s&lt;T,N&gt; will provide zero (please see motivation bellow) or more index=
 of argument to be forwarder (index should be 1based to<br>&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; uniform with standard bind). The second argument N would mea=
n actual number of argument provided to invocation of the bind (so we cane =
genereate<br>&nbsp;&nbsp; &nbsp;&nbsp; index of all arguments). The placeho=
lder position should be derived from std::integer_sequence&lt;std::<wbr>siz=
e_t, ...&gt; class in case when is_placeholder&lt;T&gt;::value<br>&nbsp; &n=
bsp; is true.<br>&nbsp; c) to main the backward compatibility the, default =
implementation of </span></span><span><span style=3D"color:rgb(34,34,34)">p=
laceholder_positions would be:<br><span style=3D"font-family:courier new,mo=
nospace">&nbsp;&nbsp;&nbsp; template&lt;typename T, std::size_t N&gt;<br>&n=
bsp; &nbsp; struct placeholder_positions :<br>&nbsp; &nbsp; &nbsp;&nbsp; </=
span></span></span><span><span style=3D"color:rgb(34,34,34)"><span style=3D=
"font-family:courier new,monospace">std::integer_sequence&lt;std::<wbr>size=
_t, std::is_placeholder&lt;T&gt;::value&gt;<br>&nbsp;&nbsp;&nbsp; {}</span>=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; so for the single argument placeholder, =
is_placeholder can be used in the same way as today, but bind depend only f=
or&nbsp; </span></span><span style=3D"font-family:courier new,monospace">p<=
/span><span><span style=3D"color:rgb(34,34,34)"><span style=3D"font-family:=
courier new,monospace">laceholder_positions<br>&nbsp; <font face=3D"arial,s=
ans-serif">to get argument&nbsp; to forward.<br><br>2. There should be 2 gr=
oup placeholders defined in the standard:<br>&nbsp;&nbsp;&nbsp; a) _all, th=
at will forward all arguments, definition using proposed specializations wo=
uld be:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face=3D"courier new,m=
onospace">template&lt;&gt;<br>&nbsp;&nbsp; struct is_placeholder&lt;_all&gt=
; : std::true_type {};<br><br>&nbsp;&nbsp; </font></font></span></span></sp=
an><span style=3D"font-family:courier new,monospace">t</span><span><span st=
yle=3D"color:rgb(34,34,34)"><span style=3D"font-family:courier new,monospac=
e">emplate&lt;std::size_t N&gt;<br>&nbsp;&nbsp; struct </span></span></span=
><span><span style=3D"color:rgb(34,34,34)"><span style=3D"font-family:couri=
er new,monospace">placeholder_positions&lt;_all, N&gt;<br>&nbsp;&nbsp;&nbsp=
;&nbsp; : shift&lt;s</span></span></span><span><span style=3D"color:rgb(34,=
34,34)"><span style=3D"font-family:courier new,monospace">td::make_integer_=
<wbr>sequence&lt;std::size_t, N&gt;, 1&gt; {} <br><span style=3D"font-famil=
y:arial,sans-serif">&nbsp; b)&nbsp; _from&lt;N&gt; that will forward argume=
nts all arguments form Nth. The _from&lt;N&gt; should be ill formed if numb=
er of arguments is less than N. For exactly N-1<br>&nbsp; &nbsp; &nbsp; &nb=
sp; arguments there should be empty sequence generated - if there is need t=
o be sure that at least N arguments, then _N, _from&lt;N+1&gt; may be used.=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Implementation:<br></span></span><=
/span></span><span><span style=3D"color:rgb(34,34,34)"><span style=3D"font-=
family:courier new,monospace"><font face=3D"arial,sans-serif">&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp; <font face=3D"courier new,monospace">template&lt;st=
d::size_t N&gt;<br>&nbsp;&nbsp; struct is_placeholder&lt;_from&lt;N&gt;&gt;=
 : std::true_type {};</font></font></span></span></span><br><span><span sty=
le=3D"color:rgb(34,34,34)"><span style=3D"font-family:courier new,monospace=
"><font face=3D"arial,sans-serif"><font face=3D"courier new,monospace">&nbs=
p;&nbsp; </font></font></span></span></span><span style=3D"font-family:cour=
ier new,monospace"><br>&nbsp;&nbsp; t</span><span><span style=3D"color:rgb(=
34,34,34)"><span style=3D"font-family:courier new,monospace">emplate&lt;std=
::size_t N&gt;<br>&nbsp;&nbsp; struct </span></span></span><span><span styl=
e=3D"color:rgb(34,34,34)"><span style=3D"font-family:courier new,monospace"=
>placeholder_positions&lt;_all, ArgCount&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp; : =
enable_if&lt;</span></span></span><span><span style=3D"color:rgb(34,34,34)"=
><span style=3D"font-family:courier new,monospace"><span><span style=3D"col=
or:rgb(34,34,34)"><span style=3D"font-family:courier new,monospace">ArgCoun=
t + 1 &lt;=3D N,</span></span></span> &nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp; shift&lt;s</span></span></span><span><span style=3D"color:rgb=
(34,34,34)"><span style=3D"font-family:courier new,monospace">td::make_inte=
ger_<wbr>sequence&lt;std::size_t, ArgCount - N&nbsp; + 1&gt;, N&gt; {}<br><=
span style=3D"font-family:arial,sans-serif">&nbsp; c) The user can define i=
ts own placeholders group via specializations.</span><br><br><font face=3D"=
arial,sans-serif">3. I would define new placeholder in the namespace std::p=
laceholders, but that may lead to the some annoying problems to the user if=
 there where named simply<br>&nbsp;&nbsp;&nbsp; all and from. Most of the c=
ode that uses bind, looks like:<br><span style=3D"font-family:courier new,m=
onospace">&nbsp;&nbsp;&nbsp; using namespace </span></font></span></span></=
span><span><span style=3D"color:rgb(34,34,34)"><span style=3D"font-family:c=
ourier new,monospace"><font face=3D"arial,sans-serif"><span><span style=3D"=
color:rgb(34,34,34)"><span style=3D"font-family:courier new,monospace"><fon=
t face=3D"arial,sans-serif"><span style=3D"font-family:courier new,monospac=
e">std::placeholders;<br>&nbsp;&nbsp;&nbsp; std::bind(f, _1, a, _2);</span>=
<br>&nbsp;&nbsp;&nbsp; While there is really low possibility to have variab=
les named _1, _2, ... in the user code, there is pretty much a chance that =
the user code would define viarbles<br>&nbsp;&nbsp;&nbsp; named all or from=
 and cause the crash of bind.&nbsp; That it the reason I choosed _all and _=
from instead, which look pretty uniform with _1. Another solution would be<=
br>&nbsp;&nbsp;&nbsp; to define it in the different namespace.<br><br>What =
are you thoughts about this idea.<br></font></span></span></span></font></s=
pan></span></span></blockquote>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to 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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_847_7630750.1374614559631--

.
