Title
bind needs to be moved
Status
c++11
Section
[func.bind.bind]
Submitter
Howard Hinnant

Created on 2008-03-17.00:00:00 last changed 161 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Change [function.objects] p2:

template<class Fn, class... Types BoundArgs>
  unspecified bind(Fn&&, Types BoundArgs&&...);
template<class R, class Fn, class... Types BoundArgs>
  unspecified bind(Fn&&, Types BoundArgs&&...);

Change [func.require]:

4 Every call wrapper ([func.def]) shall be CopyMoveConstructible. A simple call wrapper is a call wrapper that is CopyConstructible and CopyAssignable and whose copy constructor, move constructor and assignment operator do not throw exceptions. A forwarding call wrapper is a call wrapper that can be called with an argument list. [Note: in a typical implementation forwarding call wrappers have an overloaded function call operator of the form

template<class... ArgTypesUnBoundsArgs>
R operator()(ArgTypesUnBoundsArgs&&... unbound_args) cv-qual;

end note]

Change [func.bind.bind]:

Within this clause:

  • Let FD be a synonym for the type decay<F>::type.
  • Let fd be an lvalue of type FD constructed from std::forward<F>(f).
  • Let Ti be a synonym for the ith type in the template parameter pack BoundArgs.
  • Let TiD be a synonym for the type decay<Ti>::type.
  • Let ti be the ith argument in the function parameter pack bound_args.
  • Let tid be an lvalue of type TiD constructed from std::forward<Ti>(ti).
  • Let Uj be the jth deduced type of the UnBoundArgs&&... parameter of the operator() of the forwarding call wrapper.
  • Let uj be the jth argument associated with Uj.
template<class F, class... BoundArgs>
  unspecified bind(F&& f, BoundArgs&&... bound_args);

-1- Requires: is_constructible<FD, F>::value shall be true. For each Ti in BoundArgs, is_constructible<TiD, Ti>::value shall be true. F and each Ti in BoundArgs shall be CopyConstructible. INVOKE(fd, w1, w2, ..., wN) ([func.require]) shall be a valid expression for some values w1, w2, ..., wN, where N == sizeof...(bound_args).

-2- Returns: A forwarding call wrapper g with a weak result type ([func.require]). The effect of g(u1, u2, ..., uM) shall be INVOKE(fd, v1, v2, ..., vN, result_of<FD cv (V1, V2, ..., VN)>::type), where cv represents the cv-qualifiers of g and the values and types of the bound arguments v1, v2, ..., vN are determined as specified below. The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types TiD throws an exception.

-3- Throws: Nothing unless the copy constructionor of Ffd or of one of the values tid types in the BoundArgs... pack expansion throws an exception.

Remarks: The unspecified return type shall satisfy the requirements of MoveConstructible. If all of FD and TiD satisfy the requirements of CopyConstructible then the unspecified return type shall satisfy the requirements of CopyConstructible. [Note: This implies that all of FD and TiD shall be MoveConstructibleend note]

template<class R, class F, class... BoundArgs>
  unspecified bind(F&& f, BoundArgs&&... bound_args);

-4- Requires: is_constructible<FD, F>::value shall be true. For each Ti in BoundArgs, is_constructible<TiD, Ti>::value shall be true. F and each Ti in BoundArgs shall be CopyConstructible. INVOKE(fd, w1, w2, ..., wN) shall be a valid expression for some values w1, w2, ..., wN, where N == sizeof...(bound_args).

-5- Returns: A forwarding call wrapper g with a nested type result_type defined as a synonym for R. The effect of g(u1, u2, ..., uM) shall be INVOKE(fd, v1, v2, ..., vN, R), where the values and types of the bound arguments v1, v2, ..., vN are determined as specified below. The copy constructor and move constructor of the forwarding call wrapper shall throw an exception if and only if the corresponding constructor of FD or of any of the types TiD throws an exception.

-6- Throws: Nothing unless the copy constructionor of Ffd or of one of the values tid types in the BoundArgs... pack expansion throws an exception.

Remarks: The unspecified return type shall satisfy the requirements of MoveConstructible. If all of FD and TiD satisfy the requirements of CopyConstructible then the unspecified return type shall satisfy the requirements of CopyConstructible. [Note: This implies that all of FD and TiD shall be MoveConstructibleend note]

-7- The values of the bound arguments v1, v2, ..., vN and their corresponding types V1, V2, ..., VN depend on the types TiD derived from of the corresponding argument ti in bound_args of type Ti in BoundArgs in the call to bind and the cv-qualifiers cv of the call wrapper g as follows:

  • if ti TiD is of type reference_wrapper<T> the argument is tid.get() and its type Vi is T&;
  • if the value of std::is_bind_expression<TiD>::value is true the argument is tid(std::forward<Uj>(uj)... u1, u2, ..., uM) and its type Vi is result_of<TiD cv (Uj... U1&, U2&, ..., UM&)>::type;
  • if the value j of std::is_placeholder<TiD>::value is not zero the argument is std::forward<Uj>(uj) and its type Vi is Uj&&;
  • otherwise the value is tid and its type Vi is TiD cv &.
Date: 2010-10-21.18:28:33

[ Moved to Tentatively Ready after 6 positive votes on c++std-lib. ]

Date: 2009-11-15.00:00:00

[ 2009-11-15 Further updates by Peter, Chris and Daniel. ]

Date: 2009-11-07.00:00:00

[ 2009-11-07 Howard updates wording. ]

Date: 2010-10-21.18:28:33

[ 2009-10 Santa Cruz: ]

Leave as Open. Howard to provide deconceptified wording.

Date: 2010-10-21.18:28:33

[ 2009-07 Frankfurt: ]

The proposed resolution uses concepts. Leave Open.

Date: 2010-10-21.18:28:33

[ Batavia (2009-05): ]

We were going to recommend moving this issue to Tentatively Ready until we noticed potential overlap with issue 816 (q.v.).

Move to Open, and recommend both issues be considered together (and possibly merged).

Date: 2010-10-21.18:28:33

[ Post Summit Alisdair and Howard provided wording. ]

Several issues are being combined in this resolution. They are all touching the same words so this is an attempt to keep one issue from stepping on another, and a place to see the complete solution in one place.

  1. bind needs to be "moved".
  2. [func.bind.bind]/p3, p6 and p7 were accidently removed from N2798.
  3. Issue 929 argues for a way to pass by && for efficiency but retain the decaying behavior of pass by value for the thread constructor. That same solution is applicable here.
Date: 2010-10-21.18:28:33

[ San Francisco: ]

Howard to provide wording.

Date: 2008-03-17.00:00:00

Addresses US 72, JP 38 and DE 21

The functor returned by bind() should have a move constructor that requires only move construction of its contained functor and bound arguments. That way move-only functors can be passed to objects such as thread.

This issue is related to issue 816.

US 72:

bind should support move-only functors and bound arguments.

JP 38:

add the move requirement for bind's return type.

For example, assume following th1 and th2,

void f(vector<int> v) { }

vector<int> v{ ... };
thread th1([v]{ f(v); });
thread th2(bind(f, v));

When function object are set to thread, v is moved to th1's lambda expression in a Move Constructor of lambda expression because th1's lambda expression has a Move Constructor. But bind of th2's return type doesn't have the requirement of Move, so it may not moved but copied.

Add the requirement of move to get rid of this useless copy.

And also, add the MoveConstructible as well as CopyConstructible.

DE 21

The specification for bind claims twice that "the values and types for the bound arguments v1, v2, ..., vN are determined as specified below". No such specification appears to exist.

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg3905
2010-10-21 18:28:33adminsetmessages: + msg3904
2010-10-21 18:28:33adminsetmessages: + msg3903
2010-10-21 18:28:33adminsetmessages: + msg3902
2010-10-21 18:28:33adminsetmessages: + msg3901
2010-10-21 18:28:33adminsetmessages: + msg3900
2010-10-21 18:28:33adminsetmessages: + msg3899
2010-10-21 18:28:33adminsetmessages: + msg3898
2010-10-21 18:28:33adminsetmessages: + msg3897
2008-03-17 00:00:00admincreate