C++ 参考手册

位置:首页 > C++ 参考手册 >工具库 >函数对象 > std::mem_fn

定义于头文件 <functional>
template< class M, class T >
/*unspecified*/ mem_fn(M T::* pm) noexcept;
(C++11 起)
(C++20 前)
template< class M, class T >
constexpr /*unspecified*/ mem_fn(M T::* pm) noexcept;
(C++20 起)

函数模板 std::mem_fn 生成指向成员指针的包装对象,它可以存储、复制及调用指向成员指针。到对象的引用和指针(含智能指针)可在调用 std::mem_fn 时使用。

参数

pm - 指向被包装成员的指针

返回值

std::mem_fn 返回未指定类型的调用包装,该类型拥有下列成员:

std::mem_fn 返回类型

成员类型

 
类型 定义
result_type(C++17 中弃用) pm 为指向成员函数的指针,则为 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>

/* see below */ operator()(Args&&... args) /* cvref-qualifiers */

    noexcept(/* see below */);
(C++20 前)
template<class... Args>

constexpr /* see below */ operator()(Args&&... args) /* cvref-qualifiers */

    noexcept(/* see below */);
(C++20 起)

fn 为以指向成员的指针 pm 调用std::mem_fn 所返回的调用包装器。则表达式 fn(t, a2, ..., aN) 等价于 INVOKE(pm, t, a2, ..., aN) ,其中 INVOKE 是定义于可调用 (Callable) 的操作。

从而 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)...

示例

mem_fn 存储执行成员函数和成员对象:

#include <functional>
#include <iostream>
 
struct Foo {
    void display_greeting() {
        std::cout << "Hello, world.\n";
    }
    void display_number(int i) {
        std::cout << "number: " << i << '\n';
    }
    int data = 7;
};
 
int main() {
    Foo f;
 
    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';
}

输出:

Hello, world.
number: 42
data: 7

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2048 C++11 提供了不需要的重载 已移除
LWG 2489 C++11 未要求 noexcept 已要求

参阅

(C++11)
包装具有指定函数调用签名的任意类型的可调用对象
(类模板)
(C++11)
绑定一或多个实参到函数对象
(函数模板)