C++11

news/2024/7/6 22:20:38

目录

1.可变参数模板

1.1概念

1.2参数包的展开

2.stl的emplace接口

3.lambda表达式

lambda表达式形式

demo代码

4.function包装器

5.bind包装器


1.可变参数模板

1.1概念

有了可变参数模板,可以创建任意参数的函数模板和类模板。

template <class ...Args> // ...的位置,怎么规定就怎么用吧。。。。。。
int add(Args... arg)
{return 0;
}int main()
{vector<int> v;string s;add(1, 3, 4, 5, 6);add(1,'c', v,s);return 0;
}

上述代码,直接生成解决方案是没有任何问题的。

1.2参数包的展开

template<class T>
void show(T t)
{cout << t << endl;
}template<class T, class ...Args>
void show(T t,Args... arg)
{cout << t << endl;show(arg...);
}int main()
{vector<int> v;string s;show(1, 3, 4, 5, 6);cout << endl;return 0;
}

这个也不知道是哪个神人想出来的,大概思路就是,[1,3,4,5,6],第一次调用show将[1]传给t,[3,4,5,6]传给arg,第二次递归将[3]传给t,[4,5,6]传给arg,依次类推就将所有参数解包。

2.stl的emplace接口

这个也是c++11之后新添加的功能,他支持万能引用,指出可变参数

 插入一个新的元素在vector的末尾元素的后面,这个新的元素是使用args为参数构造的。

class date
{
public:date(int year = 2000, int month = 1, int day = 1):_year(year),_month(month),_day(day){cout<< "date(int year = 2000, int month = 1, int day = 1)" << endl;}private:int _year;int _month;int _day;
};int main()
{vector<date> v;v.push_back({1999,3,3});//v.push_back(1999, 3, 3);错误做法v.emplace_back(1999,3,3);return 0;
}

v.push_back({1999,3,3});就是隐式类型转换,构造出一个date临时对象,在拷贝临时对象放入vector中。

v.emplace_back(1999,3,3);直接构造一个对象,放入vector中。

emplace接口对浅拷贝的类更有意义的,对于浅拷贝emplace可以减少一次拷贝构造。

但是对于深拷贝有移动构造的类,emplace减少一次移动构造,移动构造代价很小,效率提升不明显。

3.lambda表达式

在c++98中,我们使用sort这类的接口,想要比叫大于或者是小于,必须自己写一个仿函数,非常的不人性,非常的麻烦。

template<class T>
class compare
{
public:bool operator()(T left,T right){return left > right;}
};int main()
{compare<int> cmp;vector<int>a = {1,2,4,5,6};sort(a.begin(),a.end(),cmp);for (auto num : a){cout << num << endl;}return 0;
}

在c++11中我们可以使用lambda表达式,代替仿函数。

lambda表达式形式

[ capture-list] (parameters) mutable -> return-type { statement }

capture-list:捕捉列表,用于捕捉参数,捕捉的参数是原参数的拷贝

[var]:表示值传递方式捕捉变量var

[=]:表示值传递方式捕获所有父作用域中的变量(包括this)

[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针

(parameters):参数列表,和函数的参数列表一样。

mutable:关键字,lambda默认是const,mutbable可以取消const。

return-type:返回值值,可写可不写,lambda表达式会自动推导。

{ statement }:函数体

demo代码

class goods
{
public:goods(string name = "未知", int price = 0):_name(name),_price(price){}string _name;int _price;
};int main()
{vector<goods> v = { {"苹果",3},{"香蕉",6},{"栗子",1} };sort(v.begin(), v.end(), [](goods& g1, goods& g2)->bool {return g1._price > g2._price; });for(auto g : v){cout << g._name << endl;}return 0;
}

lamdba表达式的底层还是仿函数的,lamdba表达式是可以拷贝,但是不能赋值。

int  main()
{auto lamdba1 = [] {cout << "hello word" << endl; };auto lamdba2 = [] {cout << "hello word" << endl; };lamdba1 = lamdba2;return 0;
}

错误原因就是他们两个类型不同。

4.function包装器

包装器是一个类模板,它可以用来接受,函数指针,函数对象,lamdba表达式。

#include<functional>
// 类模板原型如下
template <class T> function;     // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;

Ret是返回值,Args是函数参数。

demo代码

int add(int a,int b)
{return a + b;
}class cadd
{
public:int operator()(int a, int b){return a + b;}
};
int  main()
{function<int(int, int)> func1 = add;cout<<func1(1,3)<<endl;function<int(int, int)> func2 = cadd();cout << func2(2, 4)<<endl;function<int(int, int)> func3 = [](int a, int b)->int { return a + b; };cout << func3(2, 4) << endl;return 0;
}

5.bind包装器

bind是一个函数模板,它就像一个函数包装器(适配器),接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表
主要就是有两个功能,改变参数位置,绑定参数。
template <class Ret, class Fn, class... Args>
bind (Fn&& fn, Args&&... args);
参数fn接收一个函数,Args就是函数的参数。

_1代表的就是函数第一个参数,_1是在placeholders这个类域里的。

参数绑定

绑定的位置,与函数参数位置对应。

auto func3 = bind(sub,1,5);
cout << func3 () << endl;

成员函数的绑定

成员函数别忘记,this,每个成员函数都有一个this指针。

auto func4 = bind(&csub::sub, csub(), placeholders::_1, placeholders::_2);
cout << func4(1,7) << endl;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.cpky.cn/p/13609.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【刷题】初步认识深搜(DFS)

送给大家一句话&#xff1a; 拥有希望的人&#xff0c;和漫天的星星一样&#xff0c;是永远不会孤独的。 -- 《星游记》 初步认识深搜&#xff08;DFS&#xff09; dfs算法二叉树中的深搜Leetcode 129. 求根节点到叶节点数字之和题目描述算法思路 Leetcode 814. 二叉树剪枝题…

【Mac】iTerm for mac(终端工具)软件介绍及安装教程

软件介绍 iTerm 是 macOS 上一个非常受欢迎的终端仿真器&#xff0c;提供了比默认的 Terminal 应用更多的功能和定制选项。它是一款开源软件&#xff0c;主要用于命令行界面的操作和开发者工具。 主要特点和功能&#xff1a; 分页和标签&#xff1a; iTerm 允许用户在单个窗…

show-overflow-tooltip 解决elementui el-table标签自动换行的问题

elementui中 el-table中某一行的高度不想因为宽度不够而撑开换行展示的解决方法。可通过show-overflow-tooltip属性解决&#xff0c;如下 代码是这样的 <el-table-column width"80" prop"id" label"ID"></el-table-column> <el…

Python 挖坑式填充Excel模板内容(包括页眉/SheetName/logo)

纵览 Python处理Excel的方式--解压缩方式1、导包2、对模板文件进行解压缩3、对解压缩后文件层级进行介绍4、准备需要载入的数据5、模板挖坑6、运行替换代码7、压缩文件8、生成文件9、完成代码10、可能遇到的问题 结语 Python处理Excel的方式–解压缩方式 在处理Excel中过程中&…

HarmonyOS角落里的知识:“开发应用沉浸式效果”

概述 典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感&#xff0c;从而使用户获得最佳的UI体验。 图1 界面元素示意图 开发应用沉浸式效果主要要考虑如下…

Java露营基地预约小程序预约下单系统源码

轻松开启户外探险之旅 &#x1f31f; 露营热潮来袭&#xff0c;你准备好了吗&#xff1f; 随着人们对户外生活的热爱日益增加&#xff0c;露营已成为许多人周末和假期的首选活动。但你是否曾因找不到合适的露营基地而烦恼&#xff1f;或是因为繁琐的预约流程而错失心仪的营地…