最終更新日時(UTC):
が更新

履歴 編集

function template
<functional>

std::bind

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_argsunbound_args が次のように使われ、最終的に f の呼出しに到達する。(説明用に、 BoundArgs のそれぞれの decay された型を TiD 、値を tiUnBoundArgs のそれぞれの値を uj とおく)。

  1. Tistd::reference_wrapper<X> である場合、ti.get()ti の代わりに使用される。
  2. std::is_bind_expression<TiD>::valuetrue に評価される場合、ti(unbound_args...) の結果が ti の代わりに使用される(これは、ネストされた bind() が一度の呼び出しで再帰的に全て評価されることを示す)。
  3. std::is_placeholder<TiD>::valueが非ゼロに評価される場合、uj (ただし j = std::is_placeholder<Ti>::value+1) が ti の代わりに使用される。
  4. その他の場合、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;
}

出力

9,5

バージョン

言語

  • C++11

処理系

参照