std::mem_fn
來自 cppreference.com
定義於標頭檔案 <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-限定符 */ |
(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++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 2048 | C++11 | 提供了不必要的過載 | 已移除 |
LWG 2489 | C++11 | noexcept 不是必需的 | 需要 |
[編輯] 參閱
(C++11) |
任何可複製構造的可呼叫物件的包裝器 (類模板) |
(C++23) |
任何支援給定呼叫簽名中限定符的可呼叫物件的僅移動包裝器 (類模板) |
(C++11) |
將一個或多個引數繫結到函式物件 (函式模板) |