最終更新日時: 2024年06月11日 22時45分38秒 (JST)
Akira Takahashi が更新

履歴 編集

function template
<functional>

# std::mem_fn(C++11)

    namespace std {
      template <class R, class T>
      unspecified mem_fn(R T::* pm);            //C++11

      template <class R, class T>
      unspecified mem_fn(R T::* pm) noexcept;   //C++17

      template <class R, class T>
      constexpr unspecified mem_fn(R T::* pm) noexcept; //C++20
    }

## 概要

与えられたメンバ関数を呼び出す Callable オブジェクトを生成して返す。

## 戻り値

### C++17まで

`fn(t, a2, ..., aN)` の呼出しが `INVOKE(pm, t, a2, ..., aN)` と等価となる Callable オブジェクト `fn` を返す。

`fn` の型には、必要に応じて型の別名 `argument_type`, `first_argument_type`, `second_argument_type`, `result_type` が定義される。

### C++20から

`fn(call_args...)`の呼び出しが`invoke(pmd, call_args...)`を行うsimple call wrapperオブジェクト `fn` を返す。
ここで、`pmd`は`R T::* pmd(pm)`のように初期化された`fn`が保持するメンバポインタ、`call_args...`は`pm`の関数呼び出しに必要となる引数リストである。
引数リスト`call_args...`は完全転送される。

メンバポインタ呼び出しのためには`call_args...`の先頭に、`T`のオブジェクトもしくはそれを参照する何らかのものが無ければならない（詳細は`INVOKE`を参照）。

## 例外

投げない

## 例

    #include <functional>
    #include <memory>
    #include <iostream>

    int main() {
      auto l = std::make_shared<std::less<int>>();
      std::cout << std::boolalpha;
      std::cout << (*l)(3, 5) << std::endl;
      std::cout << std::mem_fn(&std::less<int>::operator ())(l, 3, 5) << std::endl;
      std::cout << std::bind(*l, std::placeholders::_1, 5)(3) << std::endl;

      // std::cout << std::bind(l, std::placeholders::_1, 5)(3) << std::endl;
      //   エラー！ std::shared_ptr< std::less<int> > は Callable ではない

      // mem_fn() で包むと Callable になる
      std::cout <<
          std::bind(std::mem_fn(&std::less<int>::operator ()), l, std::placeholders::_1, 5)(3)
      << std::endl;
    }

### 出力

    true
    true
    true
    true

## バージョン

### 言語

- C++11

### 処理系

- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: ??

## 参照

- LWG Issue 2048. Unnecessary `mem_fn` overloads
  - 不必要なオーバーロードを、C++14で削除
- LWG Issue 2489. mem_fn() should be noexcept
- P1065R2 constexpr INVOKE