名稱空間
變體
操作

std::mem_fn

來自 cppreference.com
 
 
 
函式物件
函式呼叫
(C++17)(C++23)
恆等函式物件
(C++20)
透明運算子包裝器
(C++14)
(C++14)
(C++14)
(C++14)  
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)
(C++14)

舊繫結器和介面卡
(直到 C++17*)
(直到 C++17*)
(直到 C++17*)
(直到 C++17*)  
(直到 C++17*)
(直到 C++17*)(直到 C++17*)(直到 C++17*)(直到 C++17*)
(直到 C++20*)
(直到 C++20*)
(直到 C++17*)(直到 C++17*)
(直到 C++17*)(直到 C++17*)

(直到 C++17*)
(直到 C++17*)(直到 C++17*)(直到 C++17*)(直到 C++17*)
(直到 C++20*)
(直到 C++20*)
 
定義於標頭檔案 <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 返回型別

成員型別

型別 定義
result_type(C++17 中已棄用) 如果 pm 是指向成員函式的指標,則為其返回型別;對於指向成員物件的指標則未定義。
argument_type(C++17 中已棄用) 如果 pm 是不帶引數的成員函式指標,則為 T*,可能帶有 cv 限定符
first_argument_type(C++17 中已棄用) 如果 pm 是帶一個引數的成員函式指標,則為 T*
second_argument_type(C++17 中已棄用) 如果 pm 是帶一個型別為 T1 的引數的成員函式指標,則為 T1
(C++20 前)

成員函式

template< class... Args >

/* 見下 */ operator()(Args&&... args) /* cvref-限定符 */

    noexcept(/* 見下 */);
(C++20 起為 constexpr)

表示式 fn(args) 等價於 INVOKE(pmd, args),其中 pmdfn 所持有的 可呼叫 物件,其型別為 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++11)
將一個或多個引數繫結到函式物件
(函式模板) [編輯]