任何定义了函数调用操作符的对象都是函数对象。C++ 支持创建、操作新的函数对象,同时也提供了许多内置的函数对象。
std::function 提供存储任意类型函数对象的支持。
std::mem_fn
template< class M, class T > | (C++11 起) (C++17 前) | |
template< class M, class T > | (C++17 起) |
函数模板 std::mem_fn
生成指向成员指针的包装对象,它可以存储、复制及调用指向成员指针。到对象的引用和指针(含智能指针)可在调用 std::mem_fn
时使用。
pm | - | 指向被包装成员的指针 |
std::mem_fn
返回未指定类型的调用包装,该类型拥有下列成员:
成员类型
| (C++20 前) |
template<class... Args> |
令 fn
为以指向成员的指针 pm
调用std::mem_fn
所返回的调用包装器。则表达式 fn(t, a2, ..., aN) 等价于 INVOKE(pm, t, a2, ..., aN) ,其中 INVOKE 是定义于可调用 (Callable) 的操作。(从而 operator()
的返回类型是std::result_of<decltype(pm)(Args&&...)>::type 。)。
完美转发 args
中的每个参数,如同用 std::forward<Args>(args)... 。
#include <functional>
#include <iostream>
struct Foo
{
void display_greeting()
{
std::cout << "Hello, world." << " " << __FUNCTION__ << " " << std::endl;
}
void display_number(int i)
{
std::cout << "number: " << i << " " << __FUNCTION__ << " " << std::endl;
}
int data = 7;
};
int main()
{
Foo f;
auto greet = std::mem_fn(&Foo::display_greeting);
greet(&f);
std::cout << "typeid(greet).name() " << typeid(greet).name() << std::endl;
std::cout << "typeid(greet).name() " << typeid(greet).name() << std::endl;
auto print_num = std::mem_fn(&Foo::display_number);
print_num(&f, 42);
std::cout << "typeid(print_num).name() " << typeid(print_num).name() << std::endl;
auto access_data = std::mem_fn(&Foo::data);
std::cout << "data: " << access_data(&f) << std::endl;
std::cout << "typeid(access_data).name() " << typeid(access_data).name() << std::endl;
return 0;
}
Hello, world. display_greeting
typeid(greet).name() St7_Mem_fnIM3FooFvvEE
typeid(greet).name() St7_Mem_fnIM3FooFvvEE
number: 42 display_number
typeid(print_num).name() St7_Mem_fnIM3FooFviEE
data: 7
typeid(access_data).name() St7_Mem_fnIM3FooiE