std::mem_fn
来自 cppreference.com
< cpp | utility | functional
在头文件 <functional> 中定义 |
||
template< class M, class T > /* unspecified */ 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 > /* see below */ operator()(Args&&... args) /* cvref-qualifiers */ |
(自 C++20 起为 constexpr) | |
表达式 fn(args) 等效于 INVOKE
(pmd, args),其中 pmd 是 fn 所持有的 Callable 对象,其类型为 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++ 标准。
DR | 应用于 | 发布的行为 | 正确行为 |
---|---|---|---|
LWG 2048 | C++11 | 提供了不必要的重载 | 已移除 |
LWG 2489 | C++11 | noexcept 不需要 | 需要 |
[编辑] 另请参阅
(C++11) |
任何可复制的可调用对象的复制包装器 (类模板) |
(C++23) |
任何在给定调用签名中支持限定符的可调用对象的移动包装器 (类模板) |
(C++11) |
将一个或多个参数绑定到函数对象 (函数模板) |