std:: mem_fn
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Old binders and adaptors | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定义于头文件
<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)
|
将一个或多个参数绑定到函数对象
(函数模板) |