252 lines
10 KiB
Markdown
252 lines
10 KiB
Markdown
[func.bind]
|
||
|
||
# 22 General utilities library [[utilities]](./#utilities)
|
||
|
||
## 22.10 Function objects [[function.objects]](function.objects#func.bind)
|
||
|
||
### 22.10.15 Function object binders [func.bind]
|
||
|
||
#### [22.10.15.1](#general) General [[func.bind.general]](func.bind.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13332)
|
||
|
||
Subclause [func.bind] describes a uniform mechanism for binding
|
||
arguments of callable objects[.](#general-1.sentence-1)
|
||
|
||
#### [22.10.15.2](#isbind) Class template is_bind_expression [[func.bind.isbind]](func.bind.isbind)
|
||
|
||
[ð](#lib:is_bind_expression)
|
||
|
||
namespace std {template<class T> struct is_bind_expression; // see below}
|
||
|
||
[1](#isbind-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13345)
|
||
|
||
The class template is_bind_expression can be used to detect function objects
|
||
generated by bind[.](#isbind-1.sentence-1)
|
||
|
||
The function template bind uses is_bind_expression to detect subexpressions[.](#isbind-1.sentence-2)
|
||
|
||
[2](#isbind-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13350)
|
||
|
||
Specializations of the is_bind_expression template shall meet
|
||
the [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#isbind-2.sentence-1)
|
||
|
||
The implementation
|
||
provides a definition that has a base characteristic oftrue_type if T is a type returned from bind,
|
||
otherwise it has a base characteristic of false_type[.](#isbind-2.sentence-2)
|
||
|
||
A program may specialize this template for a program-defined type T to have a base characteristic of true_type to indicate thatT should be treated as a subexpression in a bind call[.](#isbind-2.sentence-3)
|
||
|
||
#### [22.10.15.3](#isplace) Class template is_placeholder [[func.bind.isplace]](func.bind.isplace)
|
||
|
||
[ð](#lib:is_placeholder)
|
||
|
||
namespace std {template<class T> struct is_placeholder; // see below}
|
||
|
||
[1](#isplace-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13369)
|
||
|
||
The class template is_placeholder can be used to detect the standard placeholders_1, _2, and so on ([[func.bind.place]](#place "22.10.15.5 Placeholders"))[.](#isplace-1.sentence-1)
|
||
|
||
The function template bind usesis_placeholder to detect placeholders[.](#isplace-1.sentence-2)
|
||
|
||
[2](#isplace-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13386)
|
||
|
||
Specializations of the is_placeholder template shall meet
|
||
the [*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#isplace-2.sentence-1)
|
||
|
||
The implementation
|
||
provides a definition that has the base characteristic ofintegral_constant<int, *J*> if T is the type ofstd::placeholders::_*J*, otherwise it has a
|
||
base characteristic of integral_constant<int, 0>[.](#isplace-2.sentence-2)
|
||
|
||
A program
|
||
may specialize this template for a program-defined type T to
|
||
have a base characteristic of integral_constant<int, N> with N > 0 to indicate that T should be
|
||
treated as a placeholder type[.](#isplace-2.sentence-3)
|
||
|
||
#### [22.10.15.4](#bind) Function template bind [[func.bind.bind]](func.bind.bind)
|
||
|
||
[1](#bind-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13401)
|
||
|
||
In the text that follows:
|
||
|
||
- [(1.1)](#bind-1.1)
|
||
|
||
g is a value of the result of a bind invocation,
|
||
|
||
- [(1.2)](#bind-1.2)
|
||
|
||
FD is the type decay_t<F>,
|
||
|
||
- [(1.3)](#bind-1.3)
|
||
|
||
fd is an lvalue that
|
||
is a target object of g ([[func.def]](func.def "22.10.3 Definitions")) of type FD direct-non-list-initialized with std::forward<F>(f),
|
||
|
||
- [(1.4)](#bind-1.4)
|
||
|
||
Ti is the ith type in the template parameter pack BoundArgs,
|
||
|
||
- [(1.5)](#bind-1.5)
|
||
|
||
TDi is the type decay_t<Ti>,
|
||
|
||
- [(1.6)](#bind-1.6)
|
||
|
||
ti is the ith argument in the function parameter pack bound_args,
|
||
|
||
- [(1.7)](#bind-1.7)
|
||
|
||
tdi is a bound argument entity
|
||
of g ([[func.def]](func.def "22.10.3 Definitions")) of type TDi direct-non-list-initialized with std::forward<Ti>(ti),
|
||
|
||
- [(1.8)](#bind-1.8)
|
||
|
||
Uj is the jth deduced type of the UnBoundArgs&&... parameter
|
||
of the argument forwarding call wrapper, and
|
||
|
||
- [(1.9)](#bind-1.9)
|
||
|
||
uj is the jth argument associated with Uj[.](#bind-1.sentence-1)
|
||
|
||
[ð](#lib:bind_)
|
||
|
||
`template<class F, class... BoundArgs>
|
||
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
|
||
template<class R, class F, class... BoundArgs>
|
||
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args);
|
||
`
|
||
|
||
[2](#bind-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13430)
|
||
|
||
*Mandates*: is_constructible_v<FD, F> is true[.](#bind-2.sentence-1)
|
||
|
||
For each Ti in BoundArgs, is_constructible_v<TDi, Ti> is true[.](#bind-2.sentence-2)
|
||
|
||
[3](#bind-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13435)
|
||
|
||
*Preconditions*: FD and each TDi meet
|
||
the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#bind-3.sentence-1)
|
||
|
||
*INVOKE*(fd, w1, w2, …,wN) ([[func.require]](func.require "22.10.4 Requirements")) is a valid expression for some
|
||
values w1, w2, …, wN, whereN has the value sizeof...(bound_args)[.](#bind-3.sentence-2)
|
||
|
||
[4](#bind-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13444)
|
||
|
||
*Returns*: An argument forwarding call wrapper g ([[func.require]](func.require "22.10.4 Requirements"))[.](#bind-4.sentence-1)
|
||
|
||
A program that attempts to invoke a volatile-qualified g is ill-formed[.](#bind-4.sentence-2)
|
||
|
||
When g is not volatile-qualified, invocation ofg(u1, u2, …, uM) is expression-equivalent ([[defns.expression.equivalent]](defns.expression.equivalent "3.22 expression-equivalent")) to*INVOKE*(static_cast<Vfd>(vfd), static_cast<V1>(v1), static_cast<V2>(v2), …, static_cast<VN>(vN)) for the first overload, and*INVOKE*<R>(static_cast<Vfd>(vfd), static_cast<V1>(v1), static_cast<V2>(v2), …, static_cast<VN>(vN)) for the second overload,
|
||
where the values and types of the target argument vfd and
|
||
of the bound argumentsv1, v2, …, vN are determined as specified below[.](#bind-4.sentence-3)
|
||
|
||
[5](#bind-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13466)
|
||
|
||
*Throws*: Any exception thrown by the initialization of
|
||
the state entities of g[.](#bind-5.sentence-1)
|
||
|
||
[6](#bind-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13471)
|
||
|
||
[*Note [1](#bind-note-1)*:
|
||
|
||
If all of FD and TDi meet
|
||
the requirements of [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), then
|
||
the return type meets the requirements of [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#bind-6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[7](#bind-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13479)
|
||
|
||
The values of the [*bound arguments*](#def:bound_arguments) v1, v2, …, vN and their
|
||
corresponding types V1, V2, …, VN depend on the
|
||
types TDi derived from
|
||
the call to bind and the
|
||
cv-qualifiers cv of the call wrapper g as follows:
|
||
|
||
- [(7.1)](#bind-7.1)
|
||
|
||
if TDi is reference_wrapper<T>, the
|
||
argument is tdi.get() and its type Vi is T&;
|
||
|
||
- [(7.2)](#bind-7.2)
|
||
|
||
if the value of is_bind_expression_v<TDi> is true, the argument isstatic_cast<cv TDi&>(tdi)(std::forward<Uj>(uj)...) and its type Vi isinvoke_result_t<cv TDi&, Uj...>&&;
|
||
|
||
- [(7.3)](#bind-7.3)
|
||
|
||
if the value j of is_placeholder_v<TDi> is not zero, the argument is std::forward<Uj>(uj) and its type Vi is Uj&&;
|
||
|
||
- [(7.4)](#bind-7.4)
|
||
|
||
otherwise, the value is tdi and its type Vi is cv TDi&[.](#bind-7.sentence-1)
|
||
|
||
[8](#bind-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13507)
|
||
|
||
The value of the target argument vfd is fd and
|
||
its corresponding type Vfd is cv FD&[.](#bind-8.sentence-1)
|
||
|
||
#### [22.10.15.5](#place) Placeholders [[func.bind.place]](func.bind.place)
|
||
|
||
namespace std::placeholders {// *M* is the number of placeholders*see below* _1; *see below* _2;
|
||
⋮ *see below* _*M*;}
|
||
|
||
[1](#place-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13539)
|
||
|
||
The number *M* of placeholders isimplementation-defined[.](#place-1.sentence-1)
|
||
|
||
[2](#place-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13543)
|
||
|
||
All placeholder types meet the [*Cpp17DefaultConstructible*](utility.arg.requirements#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") and[*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements, and
|
||
their default constructors and copy/move
|
||
constructors are constexpr functions that
|
||
do not throw exceptions[.](#place-2.sentence-1)
|
||
|
||
It is implementation-defined whether
|
||
placeholder types meet the [*Cpp17CopyAssignable*](utility.arg.requirements#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements,
|
||
but if so, their copy assignment operators are
|
||
constexpr functions that do not throw exceptions[.](#place-2.sentence-2)
|
||
|
||
[3](#place-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13554)
|
||
|
||
Placeholders should be defined as:inline constexpr *unspecified* _1{};
|
||
|
||
If they are not, they are declared as:extern *unspecified* _1;
|
||
|
||
[4](#place-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L13565)
|
||
|
||
Placeholders are freestanding items ([[freestanding.item]](freestanding.item "16.3.3.7 Freestanding items"))[.](#place-4.sentence-1)
|