C++之TR1::function

Tr1::function的介绍

它是一个类模板,类的成员变量是一个函数指针。可以把它看作一个智能函数指针(和shared_ptr智能指针对比着理解)。

一. 头文件

#include<functional>

二. 使用

//t.cpp
#include "stdafx.h"
#include<iostream>
#include<functional>
using namespace std;
void foo(int i){cout<<"aaa"<<endl;}
void (*p)(int)=foo;
int _tmain(int argc, _TCHAR* argv[])
{
       function<void (int)> fm;
       fm=foo;
       (*p)(2);
       fm(2);
       return 0;
}

可以看出它和函数指针很像,但是它具有很多函数指针做不到的事情。下面慢慢说。

1. 定义一个function对象。

由于function是一个类模板,所以使用起来,首先定义一个类的对象。

Function <void (int)> fm;-----<>中第一个参数是要绑定函数的返回类型,第二个参数是要绑定的函数的参数列表。注意使用小括号括起来。

2. 像函数指针一样,这个指针需要指向某个函数。

fm=function<void (int)>(foo);

3. 由于类模板function重载了()符号。所以使用起来比函数指针更易用。

Fm(2);

下面说一下为什么要有tr1::function.也就是它相对于函数指针的优点:

1. 绑定的函数的类型

函数指针只能绑定普通的外部函数。而tr1::function可以绑定各种函数类型。

(1) 外部普通函数和类的static函数

//t.cpp
#include "stdafx.h"
#include<iostream>
#include<functional>
using namespace std;
class A{
public:
static void foo(inti){cout<<"aaa"<<endl;}
};
int _tmain(int argc, _TCHAR* argv[])
{
       function<void (int)>fm(A::foo);
       //function<void (int)> fm;fm=function<void(int)>(A::foo); also OK
       void (*p)(inti)=A::foo();//error
       fm(2);
       return 0;
}

因为外部函数和类的static很相似,所以使用起来也很相似。

(2)类的非static成员函数。

//t.cpp
#include "stdafx.h"
#include<iostream>
#include<functional>
using namespace std;
class A{
public:
void foo(int i){cout<<"aaa"<<endl;}
};
int _tmain(int argc, _TCHAR* argv[])
{
       A b;
       function<void (int)>fm=bind(&A::foo,b,tr1::placeholders::_1);//OK
       //function<void (int)> fm=b.foo();//error
       fm(2);
       return 0;
}

注意必须是&A::foo(),这个符号&不能少,这是由function决定的。这里bind中的foo只是接受一个参数,而实际上是需要两个参数,因为static函数是没有对象就存在的,而非static成员函数必须有对象之后才能存在,所以这个成员函数需要指明是哪个对象的成员函数。

(3) 绑定虚函数,呈现多态

//t.cpp
#include "stdafx.h"
#include<iostream>
#include<functional>
using namespace std;
class A{
public:
  virtual void foo(int i){cout<<"A"<<endl;}
  void fun(){
       function<void (int)>fm=bind(&A::foo,this,tr1::placeholders::_1);
       fm(2);//这里和直接调用foo();效果是一样的。并没有改变它的多态性质
}
};
class B:public A
{
public:void foo(inti){cout<<"B"<<endl;}
};
int _tmain(int argc, _TCHAR* argv[])
{
       B b;
       b.fun();
       return 0;
}

其实这里并不是function的什么特殊性质,而只是function是一个普通的类而已,不是因为它而改变多态性质。这里和直接调用foo();的效果一样。

2. 构造函数中的参数

(1) 首先是函数名,这个上面已经讲过

(2) 可以是一个函数对象!(函数对象就是一个重载了操作符”()”的类,这样类的对象可以:a(…);使用起来很像函数,所以叫做函数对象)

//t.cpp
#include "stdafx.h"
#include<iostream>
#include<functional>
using namespace std;
class A{
public:
       void operator()(int i){cout<<"A"<<endl;
       }
       void foo(){}
};
int _tmain(int argc, _TCHAR* argv[])
{
       A a;
       function<void (int)> fm(a);
       fm(2);
       return 0;
}

注意这里,居然可以把一个类对象放到function里!这好像违反了function函数指针的原意。但是注意:由于function没有提供返回它拥有的东西的函数,所以这里只能fm(2);来调用类中的重载()函数。不能调用类中的其他函数。所以它还是一个函数指针,只是这个指针指向的函数是一个类中的重载()函数罢了。

3. function类模板的其他几个member函数

(1) assign函数,为这个函数指针分配一个函数实体。

(2) swap函数,交换两个函数指针拥有的东西

(3) target函数,测试本函数指针指向的函数类型是不是为指定类型

(4) target_type函数,获取函数指针指向的函数的类型信息

不常用,也不好用,所以了解即可。

总结:其实function和函数指针很像,只是比函数指针能多指向一些特别的函数而已。

普通函数指针只能指向普通的外部函数

Function可以指向:外部函数,类的static函数,类的非static函数,类的virtual函数,类的对象(函数对象)。

时间: 2024-11-07 10:21:05

C++之TR1::function的相关文章

C++ std::tr1::function使用

1. 介绍 function 是一种通用.多态的函数封装.std::function 的实例可以对任何可以调用的 目标 进行存储.复制.和调用操作,这些目标包括函数.lambda 表达式.绑定表达式.以及其它函数对象等.(c++11起的版本可用) function(和bind一样)可以实现类似函数指针的功能,却比函数指针更加灵活(体现在占位符上面),尤其是在很多成员调用同一个函数(仅仅是参数类型不同)的时候比较方便. 特点: 可以作为函数和成员函数. 可做回调函数,取代函数指针. 可作为函数的参

std::tr1::function和bind组件

C++中std::tr1::function和bind 组件的使用 在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类的非静态成员函数时.可以参考Scott Meyers. <<Effective C++ (3rd Edition)>>. Item 35.下面具体说明其使用方法. 一.指向全局函数或静态成员函数时 因为在本质上讲全局函数和静态成员函

std::tr1::function std::tr1::bind

在C++的TR1中(Technology Report)中包含一个function模板类和bind模板函数,使用它们可以实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类 的非静态成员函数时.可以参考Scott Meyers. <<Effective C++ (3rd Edition)>>. Item 35.下面具体说明其使用方法. 一.指向全局函数或静态成员函数时 因为在本质上讲全局函数和静态成员函数没有区 别,使用方法上除了静态成员函数在引用时要在前面加域作用符

C++ TR1 Function Bind

在C++ 11出现以前,C++的事件一般是通过回调形试来实现,如 void (*func)(int,int,int),其实际上是一种函数指针,在C中调用时是直接写函数名在参数列表中,而在C++中,大部份的回调需要定义成 static.也就是静态函数.通过::作用域符,方式调用. 当然在C++TR11出现前,更早的function 与Bind 在开源库中boost 中就有,而C++11 tr1也就是借鉴了或者直接使用了boost库中的相关模板. 现在就来说说C++ tr1 中的Function 模

TR1内的组件--智能指针、function

一.智能指针 tr1::shared_ptr和tr1::weak_ptr.前者的作用有如内置指针,但会记录有多少个tr::shared_ptrs共同指向同一个对象,这便是所谓的引用计数.一旦最后一个这样的指针被销毁,也就是一旦某一个对象的引用计数为0,这个对象会被自动删除.这在非环形数据结构中防止资源泄露很有帮助,但如果两个或多个对象内含tr1::shared_ptrs并形成环状,这个环形会造成每个对象的应用计数都超过0--即使指向这个环形的所有指针都已被销毁(也就是这一群对象整体看来已无法触及

C++中str1::function和bind

在C++的TR1中(TechnologyReport)中包括一个function模板类和bind模板函数,使用它们能够实现类似函数指针的功能,但却却比函数指针更加灵活,特别是函数指向类的非静态成员函数时.能够參考Scott Meyers. <<Effective C++ (3rdEdition)>>. Item 35.以下详细说明其用法. 一.指向全局函数或静态成员函数时 由于在本质上讲全局函数和静态成员函数没有差别,用法上除了静态成员函数在引用时要在前面加域作用符classNam

c++ virturn function -- 虚函数

pure irtual function  -- 纯虚函数 先看例子 #include <iostream> using namespace std; class Polygon { protected: int width, height; public: void set_values (int a, int b) { width=a; height=b; } virtual int area() = 0 ;//{return 0;} // _vptr.Polygon show difre

Effective C++ 条款54 让自己熟悉包括TR1在内的标准程序库

1. TR1(Technical Report 1)是C++ 03标准的一个扩展,它并不属于C++ 03标准,只是一份草稿文件,用于指出下一版C++标准很可能吸收的特性.目前,它的大部分已被C++ 11采纳,成为官方标准. 2. C++ 98列出的标准库的组成: STL(Standard Template Library,标准模板库).包含容器,迭代器,算法,函数对象,各种容器适配器(container adapter)和函数对象适配器(function object adapter)等. Io

读书笔记 effective c++ Item 54 让你自己熟悉包括TR1在内的标准库

1. C++0x的历史渊源 C++标准——也就是定义语言的文档和程序库——在1998被批准.在2003年,一个小的“修复bug”版本被发布.然而标准委员会仍然在继续他们的工作,一个“2.0版本”的C++标准预计在2009年被发布(虽然所有的工作很有可能在2007年底被完成).直到现在,发布下一版C++的预计年份还没有被确定,这就解释了为什么人们把下一版C++叫做“C++0x”——C++的200x年版本. C++0x可能会包含一些有趣的新的语言特性,但是大多数新C++功能将会以标准库附加物的形式被