namespace std {
template <class F, class... BoundArgs>
unspecified bind(F&& f, BoundArgs&&... bound_args); // (1) C++11
template <class F, class... BoundArgs>
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args); // (1) C++20
template <class R, class F, class... BoundArgs>
unspecified bind(F&& f, BoundArgs&&... bound_args); // (2) C++11
template <class R, class F, class... BoundArgs>
constexpr unspecified bind(F&& f, BoundArgs&&... bound_args); // (2) C++20
}
概要
Callable オブジェクトに対し、引数を部分的に束縛(bind)する。
引数
f
-- 束縛先となる Callable オブジェクトbound_args
-- 束縛対象の値やプレースホルダ(_1
,_2
, ...)、別のbind()
呼び出し
戻り値
引数を部分束縛された Callable オブジェクト。このオブジェクトは、次のような関数オブジェクトとして扱うことができる:
struct bound_function_type {
using result_type = unspecified;
template <class... UnBoundArgs>
unspecified operator ()(UnBoundArgs&&... unbound_args) const;
};
型名 result_type
は、bind()
呼び出し時のテンプレートパラメータ R
そのもの(明示的に指定した場合)か、F
の戻り値型(F
が関数へのポインタまたはメンバ関数へのポインタである場合)か、F::result_type
(F
が型名 result_type
の定義を持つ場合)である。いずれの条件も満たさない場合、result_type
は定義されない。
bound_function_type
::operator ()()
を呼び出すと、bound_args
と unbound_args
が次のように使われ、最終的に f
の呼出しに到達する。(説明用に、 BoundArgs
のそれぞれの decay
された型を TiD
、値を ti
、UnBoundArgs
のそれぞれの値を uj
とおく)。
- 型
Ti
がstd::reference_wrapper<X>
である場合、ti.get()
がti
の代わりに使用される。 std::is_bind_expression<TiD>::value
がtrue
に評価される場合、ti(unbound_args...)
の結果がti
の代わりに使用される(これは、ネストされたbind()
が一度の呼び出しで再帰的に全て評価されることを示す)。std::is_placeholder<TiD>::value
が非ゼロに評価される場合、uj
(ただしj = std::is_placeholder<Ti>::value+1
) がti
の代わりに使用される。- その他の場合、
ti
がそのまま使用される。 上記の置換を行った後、f(ti...)
を呼び出した結果がbound_function_type
::operator ()()
の呼出し結果として返される。
注意: bound_args
は明示的に std::ref()
または std::cref()
で包まない限り、内部でコピーして保持される。他方、unbound_args
は通常の perfect forwarding が行われるため、move
で渡したあるいは一時オブジェクトを直接渡した unbound_args
を複数回プレースホルダ経由で使用すると予期しない結果になることがある。
例外
戻り値のオブジェクト内に束縛する、関数オブジェクトf
およびその引数boud_args
の初期化時に例外を投げる可能性がある。
例
#include <iostream>
#include <functional>
int add(int a, int b, int c)
{
return a + b + c;
}
class Foo {
public:
int n;
Foo(int n) : n(n) {}
Foo add(int n2) const
{
return this->n + n2;
}
};
int main()
{
// 第1引数のみを先に渡す
using namespace std::placeholders;
std::function<int(int, int)> f1 = std::bind(add, 2, _1, _2);
// 残りの引数を渡して関数を呼び出す
const int result1 = f1(3, 4);
Foo foo{2};
// thisにするもののみを先に渡す
std::function<Foo(int)> f2 = std::bind(&Foo::add, foo, _1);
// 残りの引数を渡して関数を呼び出す
const auto result2 = f2(3);
std::cout << result1 << ',' << result2.n << std::endl;
}
std::function<int(int, int)> f1 = std::bind(add, 2, _1, _2);
#include <iostream>
#include <functional>
int add(int a, int b, int c)
{
return a + b + c;
}
class Foo {
public:
int n;
Foo(int n) : n(n) {}
Foo add(int n2) const
{
return this->n + n2;
}
};
出力
9,5
バージョン
言語
- C++11
処理系
- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: ??