C++11——包装器和绑定

1.包装器

C++中有一些可调用对象,比如 函数指针,仿函数对象 lambda等等,但是他们又有缺点

因此就引出了包装器的概念

包装器 function的头文件是<functional>

我们可以用包装器包装函数指针,仿函数,lambda

int f(int a, int b)
{
	return a + b;
}

struct functor
{
	int operator()(int a, int b)
	{
		return a + b;
	}
};

int main()
{
	//包装函数指针
	function<int(int, int)> f1 = f;
	cout << f1(10, 20) << "\n";

	//包装仿函数
	function<int(int, int)>f2 = functor();
	cout << f2(10, 20) << "\n";

	//包装lambda
	function<int(int, int)>f3 = [](int a, int b) {return a + b; };
	cout << f3(10, 20) << "\n";

	return 0;
}

用包装器解决逆波兰表达式

逆波兰表达式

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;
        map<string,function<int(int,int)>>Map={
            {"+",[](int a,int b){return a+b;}},
            {"-",[](int a,int b){return a-b;}},
            {"*",[](int a,int b){return a*b;}},
            {"/",[](int a,int b){return a/b;}}
        };
        for(auto& e:tokens)
        {
            if(Map.count(e))
            {
                int right=st.top();
                st.pop();
                int left=st.top();
                st.pop();
                st.push(Map[e](left,right));
            }
            else
            {
                st.push(stoi(e));
            }
        }
        return st.top();

    }
};

如果包装成员函数指针,需要注意哪些?

对于成员函数,要传this指针,使参数匹配,如果是静态成员函数,则没有this指针,要注意区分

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double pulsd(double a, double b)
	{
		return a + b;
	}
};
int main()
{
	//对于静态成员函数,没有this指针,传参时可以不用传this指针
	function<int(int, int)> f1 = &Plus::plusi;
	cout << f1(10, 20) << "\n";

	//对于成员函数,需要传this指针,要求类型匹配
	//这里有两种写法,一种是传对象指针,一种是传对象
	function<double(Plus*,double, double)> f2 = &Plus::pulsd;
	Plus plus;
	cout << f2(&plus, 10, 20) << "\n";


	function<double(Plus, double, double)> f3 = &Plus::pulsd;
	cout << f3(Plus(), 10, 20) << "\n";

	return 0;
}

2.bind

std::bind定义在<functional>头文件里,是一个函数模板,他可以接受一个可调用对象,然后生成一个新的可调用对象,新的可调用对象的参数顺序或者参数个数可以发生改变,以此来适应原对象的参数列表,

int add(int a, int b)
{
	return a + b;
}

class Sub
{
public:
	int sub(int a, int b)
	{
		return (a - b);
	}

};
int main()
{
	//普通函数绑定
	auto f1 = bind(add, placeholders::_1, placeholders::_2);
	cout << f1(10, 20) << "\n";

	//成员函数绑定,要传this指针
	auto f2 = bind(&Sub::sub, placeholders::_1, placeholders::_2, placeholders::_3);
	Sub s1;
	cout << f2(&s1,20, 10) << "\n";

	//可以绑定this指针,然后就不需要再传this指针了,减少了传参个数
	Sub s2;
	auto f3 = bind(&Sub::sub, &s2,placeholders::_1, placeholders::_2);
	cout << f3(20, 10) << "\n";

	return 0;
}

bind的函数传参表示的含义,比如:

auto f3 = bind(&Sub::sub, &s2,placeholders::_1, placeholders::_2);

&Sub::sub :表示指定函数的地址,对于普通函数不需要加&符号,因为函数名就是地址,对于成员函数则需要加&符号;

&s2:表示成员函数的this指针,如果绑定的不是成员函数,则不需要写;

placeholders::_1, placeholders::_2 :表示需要传的参数;

bind还可以调换参数顺序

也就是说placeholders::_1永远表示传的第一个参数,placeholders::_2表示传的第二个参数,而对于fx函数来说,按照传参顺序,placeholders::_2表示a,placeholders::_1表示b,这样就实现了参数顺序的调换;

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值