使用ptr_fun、mem_fun和mem_fun_ref
2016-12-21 16:17
375 查看
一、背景引入
如果我有一个函数f和一个对象x,我希望在x上调用f,而且我在x的成员函数之外。C++给我三种不同的语法
来实现这个调用:
// 语法#1:当f是一个非成员函数
f(x);
// 语法#2:当f是一个成员函数 ,而且x是一个对象或一个对象的引用
x.f();
// 语法#3:当f是一个成员函数,而且p是一个对象的指针
p->f();
现在,假设我有一个可以测试Widget的函数,
// 测试w,如果没通过,就标记为“failed”
void test(Widget& w);
而且我有一个Widget的容器:
// vw容纳Widget
vector<Widget> vw;
要测试vw中的每个Widget,我很显然可以这么使用for_each:
// 调用#1(可以编译)
for_each(vw.begin(), vw.end(), test);
但想象test是一个Widget的成员函数而不是一个非成员函数,也就是说,Widget支持自我测试:
class Widget {
public:
// 进行自我测试;如果没通过,就把*this标记为“failed”
void test();
};
在一个完美的世界,我也将能使用for_each对vw中的每个对象调用Widget::test:
// 调用#2(不能编译)
for_each(vw.begin(), vw.end(), &Widget::test);
实际上,如果世界真的完美,我将也可以使用for_each来在Widget*指针的容器上调用Widget::test:
list<Widget*> lpw;
// lpw容纳Widget的指针,调用#3(也不能编译)
for_each(lpw.begin(), lpw.end(), &Widget::test);
二、使用方法
也许现在清楚为什么mem_fun和mem_fun_ref存在了。它们让成员函数(通常必须使用句法#2或者#3来调用的)使用句法1调用。
1、mem_fun和mem_fun_ref用法
// 同上
ist<Widget*> lpw;
...
// 这个现在可以编译了
for_each(lpw.begin(), lpw.end(), mem_fun(&Widget::test));
for_each接受一个mem_fun_t类型的对象,持有一个Widget::test的指针。对于在lpw里的每个Widget*指针,for_each使用语法#1
如果你有一个支持重画的Widget类:
class Widget {
public:
...
void redraw() const;
...
};
list<Widget> lw;
for_each( lw.begin(), lw.end(), mem_fun_ref(&Widget::redraw))
总的来说,mem_fun适配语法#3——也就是当和Widget*指针配合时Widget::test要求的——到语法1,也就是for_each用的。因此也不奇怪像mem_fun_t这样的类被称为函数对象适配器。知道这个不应该使你惊讶,完全类似上述的,mem_fun_ref函数适配语法#2到语法#1
2、ptr_fun用法
for_each(vw.begin(), vw.end(), test); // 同上,调用#1;这个可以编译
for_each(vw.begin(), vw.end(), ptr_fun(test)); // 可以编译,行为,就像上面的调用#1
如果你关于什么时候使用ptr_fun什么时候不使用而感到困惑,那就考虑每当你传递一个函数给STL组件时都使用它。STL将不在乎, 并且没有运行期的惩罚。可能出现的最坏的情况就是一些读你代码的人当看见不必要的ptr_fun使用时,可能会扬起眉毛。我认为,那有多让你操心依赖于你对扬起眉毛的敏感性。
一个与ptr_fun有关的可选策略是只有当你被迫时才使用它。如果当typedef是必要时你忽略了它,你的编译器将退回你的代码。然后你得返回去添加它。
如果我有一个函数f和一个对象x,我希望在x上调用f,而且我在x的成员函数之外。C++给我三种不同的语法
来实现这个调用:
// 语法#1:当f是一个非成员函数
f(x);
// 语法#2:当f是一个成员函数 ,而且x是一个对象或一个对象的引用
x.f();
// 语法#3:当f是一个成员函数,而且p是一个对象的指针
p->f();
现在,假设我有一个可以测试Widget的函数,
// 测试w,如果没通过,就标记为“failed”
void test(Widget& w);
而且我有一个Widget的容器:
// vw容纳Widget
vector<Widget> vw;
要测试vw中的每个Widget,我很显然可以这么使用for_each:
// 调用#1(可以编译)
for_each(vw.begin(), vw.end(), test);
但想象test是一个Widget的成员函数而不是一个非成员函数,也就是说,Widget支持自我测试:
class Widget {
public:
// 进行自我测试;如果没通过,就把*this标记为“failed”
void test();
};
在一个完美的世界,我也将能使用for_each对vw中的每个对象调用Widget::test:
// 调用#2(不能编译)
for_each(vw.begin(), vw.end(), &Widget::test);
实际上,如果世界真的完美,我将也可以使用for_each来在Widget*指针的容器上调用Widget::test:
list<Widget*> lpw;
// lpw容纳Widget的指针,调用#3(也不能编译)
for_each(lpw.begin(), lpw.end(), &Widget::test);
二、使用方法
也许现在清楚为什么mem_fun和mem_fun_ref存在了。它们让成员函数(通常必须使用句法#2或者#3来调用的)使用句法1调用。
1、mem_fun和mem_fun_ref用法
// 同上
ist<Widget*> lpw;
...
// 这个现在可以编译了
for_each(lpw.begin(), lpw.end(), mem_fun(&Widget::test));
for_each接受一个mem_fun_t类型的对象,持有一个Widget::test的指针。对于在lpw里的每个Widget*指针,for_each使用语法#1
如果你有一个支持重画的Widget类:
class Widget {
public:
...
void redraw() const;
...
};
list<Widget> lw;
for_each( lw.begin(), lw.end(), mem_fun_ref(&Widget::redraw))
总的来说,mem_fun适配语法#3——也就是当和Widget*指针配合时Widget::test要求的——到语法1,也就是for_each用的。因此也不奇怪像mem_fun_t这样的类被称为函数对象适配器。知道这个不应该使你惊讶,完全类似上述的,mem_fun_ref函数适配语法#2到语法#1
2、ptr_fun用法
for_each(vw.begin(), vw.end(), test); // 同上,调用#1;这个可以编译
for_each(vw.begin(), vw.end(), ptr_fun(test)); // 可以编译,行为,就像上面的调用#1
如果你关于什么时候使用ptr_fun什么时候不使用而感到困惑,那就考虑每当你传递一个函数给STL组件时都使用它。STL将不在乎, 并且没有运行期的惩罚。可能出现的最坏的情况就是一些读你代码的人当看见不必要的ptr_fun使用时,可能会扬起眉毛。我认为,那有多让你操心依赖于你对扬起眉毛的敏感性。
一个与ptr_fun有关的可选策略是只有当你被迫时才使用它。如果当typedef是必要时你忽略了它,你的编译器将退回你的代码。然后你得返回去添加它。
相关文章推荐
- 了解使用ptr_fun、mem_fun和mem_fun_ref的原因2(Effective stl 条款41)
- 了解使用ptr_fun、mem_fun和mem_fun_ref的原因3(Effective stl 条款41)
- ptr_fun,mem_fun,mem_fun_ref的使用
- 了解使用ptr_fun、mem_fun和mem_fun_ref的原因1(Effective stl 条款41)
- effective stl 第41条:理解ptr_fun/mem_fun/mem_fun_ref的由来
- STL的bind1st,bind2nd,mem_fun,mem_fun_ref使用示例
- 【mem_fun/mem_fun_ref】成员函数作为函数对象使用
- bind1st, bind2nd, mem_fun, mem_fun_ref,这三个函数的使用
- ptr_fun,mem_fun,mem_fun_ref 浅析
- Stl中使类成员函数成为谓词,mem_fun 和mem_fun_ref的使用
- 学习使用mem_fun、mem_fun_ref函数
- Effective STL 41 Understand the reasons for ptr_fun, mem_fun, and mem_fun_ref
- mem_fun_ref,mem_fun,not1,not2,ptr_fun
- mem_fun/mem_fun_ref
- my_mem_fun_ref将类成员函数转换为仿函数
- STL中mem_fun和mem_fun_ref的用法
- boost::bind,boost::mem_fn,std::mem_fun/mem_fun_ref 比较
- STL中仿函数(functors)、类成员和mem_fun的使用
- 另一种mem_fun_ref
- STL中mem_fun和mem_fun_ref的用法