名前空間
変種
操作

std::bind

提供: cppreference.com
< cpp‎ | utility‎ | functional
 
 
 
関数オブジェクト
関数ラッパー
(C++11)
(C++11)
バインド
bind
(C++11)
関数呼び出し
(C++17)
恒等関数オブジェクト
(C++20)
参照ラッパー
(C++11)(C++11)
演算子ラッパー
否定子
(C++17)
検索子
古いバインダとアダプタ
(C++17以前)
(C++17以前)
(C++17以前)
(C++17以前)
(C++17以前)(C++17以前)(C++17以前)(C++17以前)
(C++20以前)
(C++20以前)
(C++17以前)(C++17以前)
(C++17以前)(C++17以前)

(C++17以前)
(C++17以前)(C++17以前)(C++17以前)(C++17以前)
(C++20以前)
(C++20以前)
 
ヘッダ <functional> で定義
template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
(1) (C++11およびそれ以降)
template< class R, class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
(2) (C++11およびそれ以降)

関数テンプレート bindf に対する転送呼び出しラッパーを生成します。 このラッパーの呼び出しは args に束縛された引数のいくつかを使用して f を呼ぶことと同等です。

目次

[編集] 引数

f - いくつかの引数に束縛される Callable なオブジェクト (関数オブジェクト、関数ポインタ、関数参照、メンバ関数ポインタまたはデータメンバポインタ)
args - 名前空間 std::placeholders のプレースホルダー _1, _2, _3... で置き換えた未束縛引数を持つ、束縛する引数のリスト

[編集] 戻り値

std::is_bind_expression<T>::value == true である未規定な型 T の関数オブジェクト。 以下のメンバを持ちます。

std::bind戻り値の型

メンバオブジェクト

std::bind の戻り値の型は std::forward<F>(f) から構築された std::decay<F>::type 型のメンバオブジェクト、および args... のそれぞれについて同様に std::forward<Arg_i>(arg_i) から構築された std::decay<Arg_i>::type 型のオブジェクトをひとつずつ保持します。

コンストラクタ

std::bind の戻り値の型は、そのすべての (上で規定されている) メンバオブジェクトが CopyConstructible であれば CopyConstructible であり、そうでなければ MoveConstructible です。 この型は以下のメンバを定義します。

メンバ型 result_type

1) (C++17で非推奨) F が関数ポインタまたはメンバ関数ポインタであれば、 result_typeF の戻り値の型です。 F がネストした typedef result_type を持つクラス型であれば、 result_typeF::result_type です。 そうでなければ result_type は定義されません。

2) (C++17で非推奨) result_type は正確に R です。

(C++20以前)

メンバ関数 operator()

bind の以前の呼び出しによって取得されたオブジェクト g が関数呼び出し式 g(u1, u2, ... uM) で呼ばれた場合、 std::invoke(fd, std::forward<V1>(v1), std::forward<V2>(v2), ..., std::forward<VN>(vN)) によって行われたかのように、格納されているオブジェクトの呼び出しが行われます。 ただし fdstd::decay_t<F> 型の値であり、束縛引数 v1, v2, ..., vN の値および型は以下のように決定されます。

  • 格納されている引数 argstd::reference_wrapper<T> 型の場合 (例えば bind の呼び出しで std::ref または std::cref が使用された)、上の std::invoke 呼び出しの引数 vnarg.get() であり、型 VnT& です。 格納されている引数は呼び出された関数オブジェクトに参照渡しされます。
  • 格納されている引数 argstd::is_bind_expression<T>::value == true であるような型 T の場合 (例えば別の bind 式が bind の呼び出しに直接渡された)、 bind は関数合成を行います。 bind 部分式が返す関数オブジェクトを渡す代わりに、その部分式が先行して呼び出され、その戻り値が外側の呼び出し可能なオブジェクトに渡されます。 bind 部分式が何らかのプレースホルダー引数を持っている場合、それらは外側の bind と共有されます (u1, u2, ... から取り出されます)。 具体的には、上の std::invoke 呼び出しの引数 vnarg(std::forward<Uj>(uj)...) であり、その型 Vnstd::result_of_t<T cv &(Uj&&...)>&& です (cv 修飾は g のものと同じです)。
  • 格納されている引数 argstd::is_placeholder<T>::value != 0 であるような型 T の場合 (std::placeholders::_1, _2, _3, ... のようなプレースホルダーが bind の呼び出しの引数として使用された)、そのプレースホルダーの表す引数 (_1 の場合は u1_2 の場合は u2、など) が呼び出し可能なオブジェクトに渡されます。 上の std::invoke 呼び出しの引数 vnstd::forward<Uj>(uj) であり、対応する型 VnUj&& です。
  • そうでなければ、普通の格納されている引数 arg が呼び出し可能なオブジェクトに左辺値引数として渡されます。 上の std::invoke 呼び出しの引数 vn は単純に arg であり、対応する型 VnT cv & です。 ただし cv は g のものと同じ cv 修飾です。

g() の呼び出しに供給された引数のいくつかが g に格納されているいずれのプレースホルダーによってもマッチされない場合、未使用の引数は評価され破棄されます。

g が volatile 修飾されている場合 (つまり cv 修飾子が volatile または const volatile のいずれかの場合)、動作は未定義です。

[編集] 例外

std::forward<F>(f) からの std::decay<F>::type の構築が例外を投げる場合、または std::decay<Arg_i>::type に対する対応する std::forward<Arg_i>(arg_i) からのコンストラクタのいずれかが例外を投げる場合にのみ、例外を投げます。 ただし Arg_iArgs... args のi番目の型で arg_i はi番目の引数です。

[編集] ノート

Callable で説明されているように、非静的メンバ関数ポインタまたは非静的データメンバポインタを呼び出すとき、最初の引数はアクセスされるメンバを持つオブジェクトへの参照またはポインタ (std::shared_ptr および std::unique_ptr のようなスマートポインタも含みます) でなければなりません。

束縛される引数はコピーまたはムーブされます。 std::ref または std::cref でラップされていなければ、参照渡しされることはありません。

同じ bind 式で複数のプレースホルダーを使用する (例えば _1 を複数回使用する) ことができますが、結果は対応する引数 (u1) が左辺値またはムーブ可能でない右辺値である場合にのみ well-defined です。

[編集]

#include <random>
#include <iostream>
#include <memory>
#include <functional>
 
void f(int n1, int n2, int n3, const int& n4, int n5)
{
    std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
 
int g(int n1)
{
    return n1;
}
 
struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};
 
int main()
{
    using namespace std::placeholders;  // for _1, _2, _3...
 
    // demonstrates argument reordering and pass-by-reference
    int n = 7;
    // (_1 and _2 are from std::placeholders, and represent future
    // arguments that will be passed to f1)
    auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n);
    n = 10;
    f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
                    // makes a call to f(2, 1, 42, n, 7)
 
    // nested bind subexpressions share the placeholders
    auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
    f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
 
    // common use case: binding a RNG with a distribution
    std::default_random_engine e;
    std::uniform_int_distribution<> d(0, 10);
    auto rnd = std::bind(d, e); // a copy of e is stored in rnd
    for(int n=0; n<10; ++n)
        std::cout << rnd() << ' ';
    std::cout << '\n';
 
    // bind to a pointer to member function
    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
    f3(5);
 
    // bind to a pointer to data member
    auto f4 = std::bind(&Foo::data, _1);
    std::cout << f4(foo) << '\n';
 
    // smart pointers can be used to call members of the referenced objects, too
    std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
              << f4(std::make_unique<Foo>(foo)) << '\n';
}

出力:

2 1 42 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10

[編集] 関連項目

std::bind 式におけるバインドされない引数のためのプレースホルダ
(定数) [edit]
(C++11)
メンバポインタから関数オブジェクトを作成します
(関数テンプレート) [edit]