Namespaces
Variants

std:: mem_fn

From cppreference.net
Utilities library
Function objects
Function invocation
(C++17) (C++23)
Identity function object
(C++20)
Old binders and adaptors
( until C++17* )
( until C++17* )
( until C++17* )
( until C++17* )
( until C++17* ) ( until C++17* ) ( until C++17* ) ( until C++17* )
( until C++20* )
( until C++20* )
( until C++17* ) ( until C++17* )
( until C++17* ) ( until C++17* )

( until C++17* )
( until C++17* ) ( until C++17* ) ( until C++17* ) ( until C++17* )
( until C++20* )
( until 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 是指向成员函数的指针,则为 pm 的返回类型;对于指向成员对象的指针未定义
argument_type (C++17 中弃用) pm 是不接受参数的指向成员函数的指针,则为可能带有 cv 限定的 T*
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 ) ,其中 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++11)
将一个或多个参数绑定到函数对象
(函数模板)