std::mem_fn
From cppreference.com
< cpp | utility | functional
| ヘッダ <functional> で定義 |
||
| template< class M, class T > /* 未指定 */ mem_fn( M T::* pm ) noexcept; |
(C++11以降) (C++20 以降 constexpr) |
|
関数テンプレートstd::mem_fnは、メンバーへのポインターのラッパーオブジェクトを生成します。これは、メンバーへのポインターを格納、コピー、および呼び出すことができます。std::mem_fnを呼び出す際には、オブジェクトへの参照とポインター(スマートポインターを含む)の両方を使用できます。
目次 |
[編集] パラメーター
| pm | - | ラップされるメンバーへのポインター |
[編集] 戻り値
std::mem_fnは、次のメンバーを持つ未指定の型の呼び出しラッパーfnを返します
std::mem_fn 戻り値の型
メンバ型
|
(C++20まで) |
メンバー関数
template< class... Args > /* 以下を参照 */ operator()(Args&&... args) /* cvref-qualifiers */ |
(C++20 以降 constexpr) | |
式fn(args)は、INVOKE(pmd, args)と同等です。pmdはfnが保持する呼び出し可能オブジェクトであり、型はM T::*で、pmで直接非リスト初期化されます。
したがって、operator()の戻り値の型はstd::result_of<decltype(pm)(Args&&...)>::type または同等にstd::invoke_result_t<decltype(pm), Args&&...>であり、noexcept指定子の値はstd::is_nothrow_invocable_v<decltype(pm), Args&&...>)に等しいです。(C++17以降)。
args内の各引数は、std::forward<Args>(args)...かのように完全に転送されます。
[編集] 例
メンバー関数とメンバーオブジェクトを格納および実行するためにstd::mem_fnを使用する
このコードを実行
#include <functional> #include <iostream> #include <memory> struct Foo { void display_greeting() { std::cout << "Hello, world.\n"; } void display_number(int i) { std::cout << "number: " << i << '\n'; } int add_xy(int x, int y) { return data + x + y; } template<typename... Args> int add_many(Args... args) { return data + (args + ...); } auto add_them(auto... args) // C++20 required { return data + (args + ...); } int data = 7; }; int main() { auto f = Foo{}; auto greet = std::mem_fn(&Foo::display_greeting); greet(f); auto print_num = std::mem_fn(&Foo::display_number); print_num(f, 42); auto access_data = std::mem_fn(&Foo::data); std::cout << "data: " << access_data(f) << '\n'; auto add_xy = std::mem_fn(&Foo::add_xy); std::cout << "add_xy: " << add_xy(f, 1, 2) << '\n'; auto u = std::make_unique<Foo>(); std::cout << "access_data(u): " << access_data(u) << '\n'; std::cout << "add_xy(u, 1, 2): " << add_xy(u, 1, 2) << '\n'; auto add_many = std::mem_fn(&Foo::add_many<short, int, long>); std::cout << "add_many(u, ...): " << add_many(u, 1, 2, 3) << '\n'; auto add_them = std::mem_fn(&Foo::add_them<short, int, float, double>); std::cout << "add_them(u, ...): " << add_them(u, 5, 7, 10.0f, 13.0) << '\n'; }
出力
Hello, world. number: 42 data: 7 add_xy: 10 access_data(u): 7 add_xy(u, 1, 2): 10 add_many(u, ...): 13 add_them(u, ...): 42
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2048 | C++11 | 不要なオーバーロードが提供されています | 削除 |
| LWG 2489 | C++11 | noexceptは必須ではありません | 必要 |
[編集] 関連項目
| (C++11) |
コピー構築可能な任意の呼び出し可能オブジェクトをラップするコピー可能なラッパー (クラステンプレート) |
| (C++23) |
与えられた呼び出しシグネチャで修飾子をサポートする任意の呼び出し可能オブジェクトのムーブ専用ラッパー (クラステンプレート) |
| (C++11) |
1つ以上の引数を関数オブジェクトに束縛する (関数テンプレート) |