C++11常用特性

news2024/11/24 9:56:39

目录

1、{}初始化

2、auto

3、decltype

4、nullptr

5、范围for

6、STL容器

7、右值引用

①左值引用和右值引用

②移动构造

③移动赋值

④万能引用与完美转发

8、新的类功能

9、可变模版参数

10、lambda表达式

捕捉列表的使用

[val]:传值捕捉

[&val]:传引用捕捉

[=]

[&]

混合使用

11、包装器

function包装器

bind


C++11其实就是C++03的下一个版本,在2011年完成了C++标准,所以起名为C++11

而C++增加了140多个特性,下面只对最常用的一些特性做以说明

1、{}初始化

C++11规定一切皆可{}初始化

第一种是我们经常使用的,而二三种就是C++11规定的,=也可以省略


关于结构体:

可以看到三种方式都调用了Time的构造函数初始化


关于vector、list等容器的初始化:

可以看到是非常方便使用的,不需要我们一个一个数据去push_back了

原因是C++11增加了一个默认容器initializer_list,花括号括起来的可以当做是initializer_list的类型

并且C++11给所有容器的构造函数增加了用initializer_list初始化

list为例:

所以上面我们用花括号括起来的数据可以直接初始化vector、list等容器


容器方面对于initializer_list还有其他更方便的用法:

例如上面所举例的Time结构体,我们以前如果有一个vector<Time>,只能如下图初始化:

现在使用initializer_list就可以进行下面的方式初始化:

同样在map中,也就不需要一次次的insert了:

也是非常的方便

所以最后说明一点:C++11的一切对象都可以列表初始化,但是一般的对象还是按照以前的方式初始化,使用容器时有需求可以适当使用列表初始化


2、auto

auto我们是经常用到的,可以自动识别类型

 说起auto,就要想到范围for

auto一般使用的场景是一个变量的类型非常长,可以使用auto简便些:

从上图可以清楚看出两种方法的难易程度

但是在一定程度上auto也降低了代码的可读性,有的用户清楚unordered_map的begin返回值是什么,如果不太清楚的用户就只能通过查找资料从而确定it的类型


3、decltype

decltype可以推导一个对象的类型, 再去定义变量

例如:

b对象的类型就是a的类型int


4、nullptr

nullptr的出现是为了解决早年定义的NULL出现的bug

因为早年C++中NULL被定义为字面常量0,而0既能表示为指针常量,又能表示成整型常量

所以为了更加安全的角度考虑,增加了nullptr作为空指针


5、范围for

上面也提到过范围for,可以与auto联合使用

需要知道范围for的底层是迭代器就可以


6、STL容器

C++11新增了容器unordered_set和unordered_map

相比于set和map在效率上有很大提升,在哈希章节有提到

还有两个容器:array、forward_list

①array

array是静态的顺序表,vector是动态的顺序表

C++11创建出array这个容器,初衷是为了取代C语言中的数组,想要让C++更加容器化

例如:

arr1和arr2代表的是一样的含义

二者的区别是,C语言中的数组越界读一般检查不出来越界写是抽查处理,有时会被检查出来

而array不论读或写,只要越界就能被检查出来

而array比C语言数组多了一个检查越界的作用却被用得不多有两个原因:

第一、人们C语言数组都用的很顺手,用习惯了,突然改变一个用法不太习惯

第二、如果想要类似功能,完全可以用vector + resize完成

②forward_list

我们学过的list是双向链表,而forward_list则是单向链表

并且forward_list提供了两个函数insert_after和erase_after

insert_after是在当前位置的后面插入,因为如果是在当前位置的前面插入的话,时间复杂度就变为O(N)了,因为需要找到当前位置的前一个结点

erase_after的用法是删除掉当前位置的下一个位置的结点,理由与insert_after一样

所以这个forward_list设计的思路很勉强,并不好用

并且正常情况下,都会使用list,list相比较而言只是比forward_list多了一个prev指针,也不会在效率上慢多少


上面说的是C++11新创建的几个容器,下面说说容器内部的改变:

①、容器都支持initializer_list构造,支持初始化

②、提供了几乎没有用户的接口,例如cbegin、cend系列的接口

③、移动构造和移动赋值,提高效率

④、右值引用参数的插入,提高效率

其中的第③④点,在下面有具体讲解


7、右值引用

①左值引用和右值引用

首先需要知道的是:左值引用就是我们之前所学习的引用,并且无论左值引用还是右值引用,都是给对象起别名

关于左值:左值是可以获得它的地址或是可以对它赋值,但是定义时const修饰的左值是不能赋值的,但是仍然可以获得它的地址,所以左值特点是可以取地址的

像上图的a、b、pa、*pa都是左值

而左值引用就是对左值去别名:

aa、bb、ppa、ret就是给左值起的别名


右值不能出现在赋值符号的左边,也不能取地址

例如:字面常量、表达式返回值、函数返回值(非左值引用返回值)等

如下所示:

这三种分别对应上面所举的三种例子,都是右值

而右值引用就是对右值起别名(符号是&&):

上图的n1、n2、n3就是给右值起的别名

并且左操作数必须是左值,不能是右值,右值不能被修改,(左值中被const修饰的也不能被放到左边)像下面这种写法就会报错:


左值引用不能引用右值,const左值引用可以

例如:

因为左值引用本身就是可以被修改的,而右值是不能被改变的,所以给左值引用加上const就不能被改变,所以就不会报错了

这里的const引用的意义就是:有些函数是引用传参的,例如函数Func(T& num),这时只能传左值不能传右值,加上const,变为Func(const T& num),就左值和右值都能传入Func函数了


右值引用不能引用左值,但是可以引用move(左值)


引用的价值就是减少拷贝

左值引用在做参数和做返回值有以下好处:

做参数:a、减少拷贝,提高效率 b、做输出型参数

做返回值:a、减少拷贝,提高效率 b、引用返回,可以修改返回的对象(例如map的operator[])

但是也有些情况无法使用左值引用:

例如string中的to_string函数,string to_string(int val)

to_string函数传入一个整型val,返回的string是一个临时对象,离开作用域会被销毁,不能使用引用返回

C++98中给出的方法是to_string(int val,string& str),这样也能够提高效率,但问题就是不符合用户的使用习惯,相当于改变了函数的使用方法

因此to_string使用传值返回,效率不高,会发生深拷贝,并且如果遇到的返回值是vector<vector<T>>,效率会更低,所以引入了右值引用,可以解决上述问题


②移动构造

内置类型右值:纯右值

自定义类型右值:将亡值

例如上面所提到的to_string函数,它是传值返回:假设to_string函数return str,main函数中有一个ret接收这个值:string ret = to_string(1234);

这里原始逻辑是str拷贝构造给一个临时对象,这个临时对象再拷贝构造给ret,进行了两次深拷贝

编译器可以做以改进,变为了一个拷贝构造,相当于str直接拷贝构造给了ret

下面引入了右值引用后,string有了移动构造,即:string(string&& s),移动构造函数的参数是右值引用,移动构造的实现方法就是在移动构造内部调用swap(s),将原始的string和这个将亡值s做交换

有了移动构造后,同样有原始逻辑和编译器改进后的逻辑,原始逻辑调用两次移动构造编译器改进后调用一次移动构造

移动构造就是将这个将亡值与我们自己的string对象swap,相比于深拷贝效率大大提升


③移动赋值

有移动构造自然就有移动赋值,还是以string举例:

普通的拷贝赋值是string& operator=(const string& s)

移动赋值是:string& operator=(string&& s)

移动赋值的实现也是在函数中使用swap(s),这个操作不仅交换将亡值s,进行资源移动,获得想要的结果,还将自己不需要的资源给了将亡值,可以在函数结束后帮助释放不需要的资源

所以原本需要进行深拷贝,深拷贝的代码是比较大的,现在有了移动构造和移动赋值后,只需要移动资源即可,代价很小,不需要深拷贝,效率大大提升

下面可以验证编译器在特定清空是使用移动构造的:

调试时可以观察到,还没有运行228行时,s1s2是正常的,都是"hello"

228行s2被move了,所以s2就变为了右值,当运行完228行后,可以观察到s2为空了,这就是因为调用了移动构造,在移动构造中s2s3进行了swap,所以s2资源转移给了s3,且s3得到了s2的资源,在生命周期结束后释放了s2的资源,所以s2就为空了


在学习了右值引用,明白了移动赋值和移动构造后,上面的to_string的传值返回问题就得到了解决,使用右值引用,相当于进行资源转移效率极高,并不会像之前一样出现深拷贝问题造成效率不高的问题,所以解决了传值返回的问题

正因为C++增加的右值引用的效率很高,所以每个容器的构造和赋值函数中都新增了右值引用的方法,下面列举几个:

等等


不光赋值和构造函数使用了右值引用,STL容器的插入接口也提供了右值引用版本

例如push_back、insert

右值引用的使用,使得在插入过程中,如果传递对象是右值,同样可以进行资源转移,减少拷贝,提高效率


④万能引用与完美转发

关于万能引用举个例子:在函数模版中,参数使用右值引用,这时称之为万能引用,也叫引用折叠

例如上图的函数模板,参数部分t是右值,func函数重载,满足哪个func的参数要求,就进入哪个func,用来验证传入t的属性

传参时无论左值还是右值都能传入Test中,且传入后都会变为左值引用,即原本是左值或右值,传入Test后,都变为左值;原本是const左值或const右值,传入Test后,都变为const左值

而如果想要保持t引用对象的属性,这时就要引入完美转发的概念,即在Test中,使用t时加forward<T>,如下图:

完美转发后,符合传入t对象的属性


8、新的类功能

C++11前,有6个默认成员函数,这6个函数我们不写编译器会自动生成:

构造函数、析构函数、拷贝构造函数、拷贝赋值函数、取地址重载、const取地址重载

C++11后又多了2个,变为了8个默认成员函数:

移动构造函数、移动赋值运算符重载

移动构造和移动赋值就是针对右值拷贝的,这两个新增的默认成员函数自己生成的条件和上面六个函数不同,如下:

①、如果自己没有实现移动构造函数并且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,编译器才会自动生成一个默认移动构造。

默认的移动构造中,对于内置类型完成值拷贝自定义类型的成员则需要看这个成员是否实现了移动构造,如果实现了就调用移动构造,如果没实现就调用拷贝构造

②、移动赋值和移动构造非常类似

如果自己没有实现移动赋值重载函数并且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,编译器才会自动生成一个默认移动赋值。

默认的移动赋值中,对于内置类型完成值拷贝自定义类型的成员则需要看这个成员是否实现了移动赋值,如果实现了就调用移动赋值,如果没实现就调用拷贝赋值

也有一个关键字,可以强制生成:default,例如强制生成Date类的移动构造:

Date(Date&& d) = default

如果不想让编译器执行某个函数,也有个关键字delete可以实现,例如不想让Date实现拷贝:

Date(const Date& d) = delete

上面的default和delete关键字功能是C++11新增的功能,了解即可

final和override关键字在继承那一节说到过用法,也是C++11提供的新功能

final:修饰一个类不能被继承,修饰虚函数不能被重写

override:放在子类中,检查子类的虚函数是否重写,没重写会报错


9、可变模版参数

可变参数这个概念在printf、scanf就出现过

表示不知道需要几个参数,所以语法中就给了可变参数这个概念,即表示零到多个参数

所以就有了一个基本可变参数即函数模版:

template<class ...Args>

void test(Args... args)

Args是一个模版参数包,args是一个函数形参参数包

参数包可以包括0到任意个模版参数

如上图,可以往test中传入不同数量、不同类型的参数,test中的sizeof...(args)是计算传入了几个参数,需要注意sizeof的格式,三个点在括号前面


10、lambda表达式

lambda又叫匿名函数

lambda底层其实就是一个仿函数的类型

lambda表达式书写格式:

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

capture-list是捕捉列表,parameters是参数列表,return-type是返回值类型,statement是函数体实现

我们可以发现,lambda的组成和函数差不多,相比于函数少了函数名,多了捕捉列表

->return-type:返回值类型,在明确返回值类型的情况下,一般都会省略,由编译器进行推导

parameters:参数列表,无参的时候可以省略

mutable:可以取消常量属性,也就是可以被修改,因为lambda函数总是一个const函数,平时也不太需要,可以省略,但是在使用mutable时参数列表不能为空

capture-list(捕捉列表)和statement(函数体)是不能省略的

所以最简单的lambda是:[]{};即该lambda不做任何事情

下面举一个简单的lambda的例子,简单的减法:

返回值->int是可以省略的,也可以写做auto Sub = [](int a, int b){return a - b; };

如果函数体实现需要多行代码,也可以像平常写函数一样,一行一行展现,例如交换函数:

图中的三种方式都可以,将函数体实现分成多行展现,可读性更强


下面举个使用mutable的例子:

通过观察可以发现,我们在使用lambda函数时,将参数列表为空,在捕捉列表中写了a,b(需要注意的是捕捉列表里的变量必须是同一个作用域里的才能捕捉到),然后在()后面加上了mutable

如果不加mutable是不能实现swap函数的,因为lambda函数是一个const函数,const是不能交换的,所以想要交换需要加上mutable

但是最终观察打印结果发现a和b的值并没有交换,原因是:加上mutable后变量可以交换,但是也只是在这个swap函数里面交换a和b,并不影响外面的a和b

因此上面总结时说到,一般不使用mutable都会省略,因为在大部分情况下mutable确实没有起到作用


lambda函数在使用仿函数的情况下也非常有用,例如有一个学生的结构体,里面有姓名、年龄、身高等属性,我们想要使用sort进行排序,是需要传入仿函数的,因为我们可以排序的参考项很多,姓名、年龄、身高都可以作为排序的参照,所以按照以前使用的方法,如果排列方法都想拥有,需要写六个仿函数,分别是姓名、年龄、身高的升序和降序,并且这六个仿函数还需要考虑起名的问题,如果名称起的不好也会造成使用方面的问题

如果使用lambda函数,直接在sort中传入lambda即可,例如:

上图中,第一个红框就是按年龄升序排列,第二个红框就是按身高降序排列

并不需要考虑这几个仿函数的名称怎么取比较合适这种问题,可读性是比较高的


捕捉列表的使用

[val]:传值捕捉

传值捕捉相当于拷贝捕捉过来的,上面的swap例子就是传值捕捉

[&val]:传引用捕捉

上面所举例子最终并没有成功交换a和b,需要改变捕捉列表才能实现:

在捕捉列表中,a和b前都加上了&,表示传引用捕捉,就能够成功交换a和b了

[=]

[=]表示值传递的方式捕捉作用域中所有的变量,包括this(当前函数中的,包括全局变量)

[&]

[&]表示引用的方式捕捉作用域中所有的变量,包括this(当前函数中的,包括全局变量) 


混合使用

[=, &x, &y]:表示以引用的方式捕捉x和y,值传递的方式捕捉其他所有变量

[&, a, b]:表示以值传递的方式捕捉a和b,以引用的方式捕捉其他所有变量

需要注意的是,不允许这种写法:[=, x, y],因为=本身就已经表示以值传递的方式捕捉所有变量,x、y表示的意思也是以值传递的方式捕捉,所以就重复这个含义了,不允许

同样[&, &a, &b]也是不被允许的,所以这里的混合使用,必须前后是不同的捕捉方式才能被允许

这里除a外,剩下的变量都是引用捕捉,所以可以改变大小


11、包装器

function包装器

function包装器是在头文件functional里的,类模板原型是这样的:

template class Ret, class... Args>

class functionRet(Args...)>;

其中Ret是返回值类型,Args是参数的参数包


看下面的样例引入包装器概念:

有个函数模板Board,里面有个静态变量num,++num与&num用来判别实例化了几份对象出来

通过观察结果:

可以发现函数模版Board实例化了三份对象,因为每一个静态成员num的地址都不同

那么如果想让这个函数模板只实例化一份对象,就需要用到包装器了

这里插入一点,有一个概念叫事件响应,类比于游戏中的体现就是按一个键就会释放对应的技能,如果将这个键当做string存入map中,那所发生的这个响应就是相当于要调用某个函数,但是这里的函数可能是很多种样式的,map的第二个类型不好传入,所以这里就需要用包装器包装一下,无论什么类型都可以统一传入


function包装器需要传入返回值类型和参数包

如下所示:

function<int(int, int)>,其中int(int, int),第一个int是返回值类型,括号中的是参数包


如果想包装类中的成员函数:

静态成员函数直接使用类作用限定符::即可

普通成员函数不光需要类作用限定符::,还需要在前面加上&,且传入时需要多传入一个对象进去,因为成员函数并不能直接调用,需要一个对象才能调用


所以在理解了包装器的使用后,我们上面实例化三份的代码就可以引入包装器:

分别给Board函数模版传入的第一个参数变为了f1、f2、f3,观察运行结果:

可以发现num的地址都一样,且每次++num也都是上一次++后的值,说明只实例化出了一份

所以包装器就是无论你可调用的对象是函数指针、函数对象、lambda表达式对象等等,都可以包装成统一的类型


bind

bind其实就是一个函数适配器

原型如下:

fn就是可调用对象,args就是参数包

bind里定义了一个命名空间placeholders,表示占位

其中的_1、_2、_3...就代表绑定对象的形参,即_1、_2、_3分别代表第一个、第二个、第三个...形参

使用_1、_2时,可以placeholders::_1,如果觉得太长了,可以using namespace placeholders,将这个placeholders命名空间展开,这样就可以在代码中直接使用_1、_2了

bind可以改变参数顺序:

可以看到,原本是5-2==3,经过bind,将_1,_2更换位置,再执行bindSub时就变为2-5==-3了

_1代表第一个参数,_2代表第二个参数,_1,_2更换位置就表示第一个和第二个参数更换位置了

bind可以改变参数个数:

上面说到过如果想包装类中的普通成员函数,需要多一个参数:

如果我们想要类中的Sub函数使用时也和Add函数一样,不需要额外传一个参数,这时用bind就能做到:

我们知道每次调用f1时第一个参数都必须是一个对象,因为成员函数需要对象才能调用,所以使用bind时传入Cal(),匿名对象,绑定这个参数,然后再传入_1、_2,第一二个形参,这样就可以做到在调用时,不用多传入一个参数,直接传入数值即可

需要注意的是,bind只能绑定死固定的参数,这里的Cal()每次使用Sub时都要传,所以可以绑定

下面这种情况也适用:

Mul函数有三个参数,其中第三个参数num是固定的,也想像上面的Sub和Add函数一样使用,就可以使用bind,将第三个参数直接给定数值绑定死,这样使用f3时,就不需要传入第三个参数了


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

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

相关文章

ChatGPT生产力|中科院学术ChatGPT优化配置

资源链接&#xff1a;GitHub - binary-husky/gpt_academic b站配置讲解链接&#xff1a;chatgpt-academic 新手运行官方精简指南&#xff08;科研chatgpt拓展&#xff09; 某知配置图文讲解&#xff1a;图文详解&#xff1a;在windows中部署ChatGPT学术版 - 知乎 (zhihu.com) 一…

经典OJ题:随机链表的复制

目录 题目&#xff1a; 本题的解图关键在于画图与看图&#xff01; 思路分析&#xff1a; 方法一&#xff1a;暴力求解法。 方法二&#xff1a;插入法 方法解析&#xff1a; 步骤一、插入 步骤二、 处理每一个copy的randdom指针⭐————重点 步骤三、拆卸节点 代码…

轻松与任何 SQL 数据库集成:Directus 助你无代码开发 | 开源日报 No.69

Ebazhanov/linkedin-skill-assessments-quizzes Stars: 26.5k License: AGPL-3.0 这个项目是一个 LinkedIn 技能评估答案的存储库。它提供了各种领域和主题的问题和答案&#xff0c;以帮助用户更好地学习新概念并准备相关考试。该项目具有以下核心优势&#xff1a; 提供多语…

HarmonyOS开发:UI开展前的阶段总结

前言 关于HarmonyOS&#xff0c;陆陆续续总结了有14篇的文章&#xff0c;大家可以发现&#xff0c;没有一篇是关于UI相关的&#xff0c;不是自己没有分享的打算&#xff0c;而是对于这些UI而言&#xff0c;官方都有着一系列的文档输出&#xff0c;如果我再一一的分享&#xff0…

SPSS线性回归

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

高级运维学习(十五)Zabbix监控(二)

一 Zabbix 报警机制 1 基本概念 自定义的监控项默认不会自动报警首页也不会提示错误需要配置触发器与报警动作才可以自动报警 2 概念介绍 &#xff08;1&#xff09;触发器 (trigger) 表达式&#xff0c;如内存不足300M&#xff0c;用户超过30个等 当触发条件发生后&a…

【自然语言处理】基于python的问答系统实现

一&#xff0c;文件准备 该问答系统是基于已知的问题和其一一对应的答案进行实现的。首先需要准备两个文本文件&#xff0c;分别命名为“question.txt”和“answer.txt”&#xff0c;分别是问题文件和答案文件&#xff0c;每一行是一个问题以及对应的答案。 问题文件: 中国的首…

Pytorch模型使用与修改、保存与加载

模型的使用及修改、保存与加载 以图像处理中torchvision为例&#xff0c;PyTorch通过torchvision.models模块提供了更多的预训练模型. 在图像分类当中&#xff0c;包括许多模型 import torchvision import warnings import torch warnings.filterwarnings("ignore&quo…

3D Gaussian Splatting:用于实时的辐射场渲染

Kerbl B, Kopanas G, Leimkhler T, et al. 3d gaussian splatting for real-time radiance field rendering[J]. ACM Transactions on Graphics (ToG), 2023, 42(4): 1-14. 3D Gaussian Splatting 是 Siggraph 2023 的 Best Paper&#xff0c;法国团队在会议上展示了其实现的最…

软件测试|iOS 自动化测试——技术方案、环境配置

移动端的自动化测试&#xff0c;最常见的是 Android 自动化测试&#xff0c;我个人觉得 Android 的测试优先级会更高&#xff0c;也更开放&#xff0c;更容易测试&#xff1b;而 iOS 相较于 Android 要安全稳定的多&#xff0c;但也是一个必须测试的方向&#xff0c;这个系列文…

Bean作用域

从笔者之前的博客&#xff0c;我们可以看出 Spring 是⽤来读取和存储 Bean&#xff0c;因此在 Spring 中 Bean 是最核⼼的操作 资源&#xff0c;所以接下来我们深⼊学习⼀下 Bean 对象&#xff1a;Bean作用域&#xff01; 限定程序中变量的可用范围叫做作用域&#xff01;或者…

【遮天】荒古禁地采取圣药,姬老自己走上绝路,故事扣人心悬

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫资讯。 深度爆料&#xff0c;《遮天》动漫第30话最新剧情解析&#xff0c;姬云峰&#xff0c;姬家的长老&#xff0c;地位崇高&#xff0c;深受家族成员的尊敬和信赖。他的智慧和经验在家族中享有极高的声望&#xf…

【MATLAB源码-第72期】基于matlab的OFDM-IM索引调制系统在高斯,瑞利,莱斯信道误码率对比,对比传统OFDM系统。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 OFDM-IM索引调制技术是一种新型的无线通信技术&#xff0c;它将正交频分复用&#xff08;OFDM&#xff09;和索引调制&#xff08;IM&#xff09;相结合&#xff0c;以提高频谱效率和系统容量。OFDM-IM索引调制技术的基本思想…

【字符串】【完整程序+倒序输出+每个区间倒序输出】KamaCoder55

【字符串】【完整程序倒序输出每个区间倒序输出】KamaCoder55 解法1 完整程序书写kama 倒序输出每个区间倒序输出 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法1 完整程序书写kama 倒序输出每个区间倒序输出 时间…

docker部署redis6

前言&#xff1a;在离线服务器上&#xff08;无联网&#xff09;&#xff0c;部署redis的方式&#xff0c;采用docker是比较方便的。下面将描述如何使用docker部署单机版redis 环境&#xff1a;centos 7 redis&#xff1a;6.2.14 docker&#xff1a;20.10.9 1.下载 redis 镜像…

取产品之道、赚效率的钱,锅圈万店背后的赢家法则

万店&#xff0c;一个真正意义上的规模壁垒&#xff0c;当它出现在任何行业时&#xff0c;都意味着这个玩家身上存在许多领先于行业的优势。 这一点&#xff0c;在刚于近日登录港交所的锅圈食品&#xff08;以下简称“锅圈”&#xff09;身上尤其明显——2017年&#xff0c;锅…

浅谈插接母线温度在线监测系统研究与应用-安科瑞黄安南

摘要 低压封闭式插接母线是供配电设施的关键部件&#xff0c;安装在生产车间内部高空&#xff0c;不易保养和维护&#xff0c;在安装不良或保养不当时易发生故障。插接点温度的异常变化与母线故障的发生有着密切的关系&#xff0c;以汽车整车制造工厂为例&#xff0c;提出母线接…

梓航DIY无限建站-3.5.8(企业官网 应用首页 PC建站 14套模板切换,自由组合页面,无限多开)

梓航DIY无限建站是一款支持无限建站的公众号应用。 自定义网址 全局样式设置 极速建站 更灵活 更方便。 1、默认页面指定设置&#xff0c;更灵活、更方便&#xff1b; 2、全局样式设置&#xff0c;减少页面重复设置工作&#xff1b; 3、不限数量网站制作装修&#xff08;想做…

VR虚拟现实:VR技术如何进行原型制作

VR虚拟现实原型制作 利用VR虚拟现实软件进行原型制作可以用于增强原型测试期间的沉浸感&#xff0c;减少产品设计迭代次数&#xff0c;并将与产品原型制作相关的成本降低40-65%。 VR虚拟现实原型制作市场规模 用于原型制作的虚拟现实 (VR) 市场在 2017 年估计为 2.104 亿美元…