C++ STL mem_fun / mem_fun_ref /
说明
这些函数都作用如其名称:member function,都是为了取得成员函数对象。
mem_fun和mem_fun_ref是C++98标准的。
mem_fn是C++11标准的,可以取代mem_fun和mem_fun_ref。
mem_fun是指针版的把成员函数转换成函数对象。
mem_fun_ref是引用版的把成员函数转换成函数对象。
mem_fn则是无论指针还是引用都可以把成员函数转换为函数对象。
下面详细说明。
头文件
#include <functional>
mem_fun_ref
例子如下:
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
vector<string> numbers;
// populate vector:
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
vector <int> lengths (numbers.size());
transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun_ref(&string::length));
for (int i=0; i<5; i++) {
cout << numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
运行结果如下:
one has 3 letters.
two has 3 letters.
three has 5 letters.
four has 4 letters.
five has 4 letters.
代码 transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun_ref(&string::length));中mem_fun_ref取得string的成员函数length(),从而取得numbers中每个string对象的长度,存入lengths容器中
mem_fun
如果上述numbers容器存储的不是string对象,而是string指针,则不能使用mem_fun_ref,而应该使用mem_fun,代码如下:
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
vector <string*> numbers;
// populate vector of pointers:
numbers.push_back ( new string ("one") );
numbers.push_back ( new string ("two") );
numbers.push_back ( new string ("three") );
numbers.push_back ( new string ("four") );
numbers.push_back ( new string ("five") );
vector <int> lengths ( numbers.size() );
transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fun(&string::length));
for (int i=0; i<5; i++) {
cout << *numbers[i] << " has " << lengths[i] << " letters.\n";
}
// deallocate strings:
for (vector<string*>::iterator it = numbers.begin(); it!=numbers.end(); ++it)
delete *it;
return 0;
}
结果如下:
one has 3 letters.
two has 3 letters.
three has 5 letters.
four has 4 letters.
five has 4 letters.
mem_fn
mem_fn则无论是指针还是引用都可以使用,是C++11标准的,上面的例子可以使用mem_fn替代如下:
只要把mem_fun_ref或者mem_fun改成mem_fn即可。
指针
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
vector <string*> numbers;
// populate vector of pointers:
numbers.push_back ( new string ("one") );
numbers.push_back ( new string ("two") );
numbers.push_back ( new string ("three") );
numbers.push_back ( new string ("four") );
numbers.push_back ( new string ("five") );
vector <int> lengths ( numbers.size() );
transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fn(&string::length));
for (int i=0; i<5; i++) {
cout << *numbers[i] << " has " << lengths[i] << " letters.\n";
}
// deallocate strings:
for (vector<string*>::iterator it = numbers.begin(); it!=numbers.end(); ++it)
delete *it;
return 0;
}
引用
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
vector<string> numbers;
// populate vector:
numbers.push_back("one");
numbers.push_back("two");
numbers.push_back("three");
numbers.push_back("four");
numbers.push_back("five");
vector <int> lengths (numbers.size());
transform (numbers.begin(), numbers.end(), lengths.begin(), mem_fn(&string::length));
for (int i=0; i<5; i++) {
cout << numbers[i] << " has " << lengths[i] << " letters.\n";
}
return 0;
}
结果都是:
one has 3 letters.
two has 3 letters.
three has 5 letters.
four has 4 letters.
five has 4 letters.
扩展
mem_fun_ref mem_fun mem_fn都是针对无参数函数的。
bind可替代它们,且还可以使用占位符来转换有参数的函数。
具体使用可参考:
https://zh.cppreference.com/w/cpp/utility/functional/bind
参考
http://www.cplusplus.com/reference/functional/mem_fun/
http://www.cplusplus.com/reference/functional/mem_fun_ref/
http://www.cplusplus.com/reference/functional/mem_fn/