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++14まで
fn(t, a2, ..., aN) の呼出しが INVOKE(pm, t, a2, ..., aN) と等価となる Callable オブジェクト fn を返す。
fn の型には、必要に応じて型の別名 argument_type, first_argument_type, second_argument_type, result_type が定義される。
C++17から
C++14までと同様だが、fnがsimple call wrapper(引数を完全転送する呼び出しラッパー)であることが要求される。すなわち、右辺値の実引数は右辺値参照として、左辺値の実引数は左辺値参照として、それぞれpmへ渡される。これにより、値渡しのパラメータを持つメンバ関数ポインタに対して余分なコピーやムーブが発生しないことが保証される。
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_fnoverloads- 不必要なオーバーロードを、C++14で削除
- LWG Issue 2486.
mem_fn()should be required to use perfect forwardingmem_fnが返すオブジェクトが引数を完全転送するsimple call wrapperであることが要求された- この修正は欠陥報告(DR)であり、C++11以降に遡及して適用される。引数の転送方法は元の規定では未規定であり、処理系は当初から完全転送していたため
- LWG Issue 2489. mem_fn() should be noexcept
- P1065R2 constexpr INVOKE