当前位置: 首页 > news >正文

【C++】C++11常用特性梳理

C++11特性梳理

  • 1. 列表初始化
  • 2. auto & decltype
  • 3. 右值引用
    • 3.1. 左右值引用比较
    • 3.2. 右值引用的意义
    • 3.3. 万能引用与完美转发
    • 3.4. 移动构造与移动赋值
  • 4. default & delete
  • 5. 可变参数模板
  • 6. push_back 与 emplace_back
  • 7. lambda表达式
    • 7.1. 捕捉列表
  • 8. function包装器
    • 8.1. bind

C++11是继C++98之后,第二个真正意义上的标准。C++11增加的语法特性非常多,这里主要介绍实际比较实用的语法。
可以从C++官网对C++11版本特性进行全面的了解:https://en.cppreference.com/w/cpp/11

1. 列表初始化

C++11中的{}不仅可以用来初始化数组,已经扩展到可以用来初始化C++11的一切对象,而且使用时等号(=)可有可无。

void Test1()
{int a1 = { 1 };int a2{ 2 };vector<int> v1 = { 1,2,3,4,5 };vector<int> v2{ 1,2,3,4,5 };map<int, string> m1 = { {1, "one"}, {2, "two"} };map<int, string> m2{ {1, "one"}, {2, "two"} };// 也可以用在new表达式中int* p = new int[4]{ 0 };
}

注意一点:列表初始化,如果出现类型截断,是会报警告或者错误的。short c = 65535; short d { 65535 }; // err
STL中的很多容器能支持{}的初始化,其实是因为增加了std::initializer_list作为构造函数参数的设计,这样使容器的初始化更方便了。operator=同理。
在这里插入图片描述
std::initializer_list又是什么类型呢?

void Test2()
{auto il = { 1,2,3 };cout << typeid(il).name() << endl;
}

在这里插入图片描述
可以看到,{}对象其实就是std::initializer_list类型的对象。
这里建议,如果在使用容器时有大括号{}初始化的需求,可以选择使用;其它地方尽量不要使用,来保持语言风格的一致性。

2. auto & decltype

auto在C++98中是一个存储类型的说明符,但实质上没有什么价值。所以C++11中,auto就弃用了之前的用法,将其用于实现自动类型推导。auto此时仅仅只是占位符,编译阶段编译器根据初始化表达式推演出实际类型之后会替换auto

void Test3()
{int i = 10;auto p = i;auto pf = strcpy;cout << typeid(p).name() << endl;cout << typeid(pf).name() << endl;
}

在这里插入图片描述

decltype关键字可以将对象的类型声明为表达式生成的类型。

void Test4()
{char c = 'a';int i = 1;decltype(c * i) d1;decltype(strcpy) d2;cout << typeid(d1).name() << endl;cout << typeid(d2).name() << endl;
}

在这里插入图片描述

3. 右值引用

有右值引用,自然也有左值引用。其实C++11之前所学的引用都叫做左值引用。但无论左值引用还是右值引用,都是给对象取别名。
对于左值,我们可以取它的地址+对它赋值。但经过const修饰的左值可以取它的地址,却不能对它赋值。
对于右值,是不能取其地址的。
左值可以出现在赋值符号左边,右值可以出现在赋值符号右边,但反过来就不行。

void Test5()
{int i = 1;int* pi = &i;// 左值引用,给左值取别名int& ri = i; // 变量int*& rpi = pi; // 变量int& r = *pi; // 指针解引用double d = 2.2;// 右值引用,给右值取别名int&& rr1 = 10; // 字面常量double&& rr2 = i + d; // 表达式返回值
}

虽然右值不能被取地址,但右值引用后,会导致右值被存储到特定位置,从而可以取到该位置的地址。

void Test6()
{int&& rr1 = 10; // 右值引用cout << rr1 << endl;cout << &rr1 << endl; // 可以取地址rr1 = 20; // 可以赋值cout << rr1 << endl;cout << &rr1 << endl; // 可以取地址
}

在这里插入图片描述

3.1. 左右值引用比较

左值引用只能引用左值,不能引用右值;但const左值引用既可以引用左值,也可以引用右值。
右值引用只能引用右值,不能引用左值;但右值引用可以引用move以后的左值。

void Test7()
{int i = 10;int& r1 = i;//int& r2 = 10; // errconst int& r3 = i;const int& r4 = 10;//int&& r5 = i; // errint&& r6 = 10;int&& r7 = move(i);
}

3.2. 右值引用的意义

左值引用既可以引用左值,又可以通过const修饰引用右值,那为什么还要提出右值引用呢?
右值引用的加入其实是对左值引用一些缺陷上的补足。
比如说,stackpop接口返回值是voidvoid pop();)。但是如果要将返回值进行修改,使pop的同时返回其弹出的元素,那该如何设计其返回值类型呢?
如果设计成传值返回,当返回值需要深拷贝时,就会对效率造成影响。
如果设计成传引用返回,如果是左值引用,当出了函数作用域,返回的对象就不存在了,即引用也失效了。
此时,只能设计成右值引用返回。设计成右值引用,把将要被销毁的对象的资源转移出来,可以继续使用,而且不需要担心深拷贝的问题,填补了左值引用使用上的一些缺陷。
右值引用可以通过移动构造或移动赋值,对返回值是右值(将亡值)的资源进行转义,减少拷贝,延长资源生命周期。

3.3. 万能引用与完美转发

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }// 模板中的&&不是右值引用,而是万能引用/引用折叠,其提供了既能接收左值又能接收右值的能力
// 但在接收之后的使用中,值类型都退化成了左值
template<typename T>
void PerfectForward(T&& t)
{Fun(t);
}void Test8()
{int i = 1;PerfectForward(i);  // 左值PerfectForward(move(i)); // 右值const int ci = 2;PerfectForward(ci); // const 左值PerfectForward(move(ci)); // const 右值
}

在这里插入图片描述

// 如果想要在传递过程中保持最初的左值或右值属性,就需要用到完美转发
template<typename T>
void PerfectForward(T&& t)
{Fun(forward<T>(t));
}

在这里插入图片描述

3.4. 移动构造与移动赋值

C++11STL容器中都是增加了移动构造和移动赋值的。
在这里插入图片描述
移动构造和移动赋值是C++11新增的两个默认成员函数。
当没有自己实现移动构造函数,且没有实现析构、拷贝构造、拷贝赋值中的任何一个函数。那么编译器会自动生成一个默认的移动构造。其对于内置类型成员会执行按字节拷贝(值拷贝);对于自定义类型成员,会看这个成员是否实现了移动构造,如果实现了就调用,没有实现就调用拷贝构造。移动赋值同理。

4. default & delete

default和delete的使用可以让我们更好地控制默认函数的生成。
default可以强制某个默认函数的生成。比如:提供拷贝构造后,移动构造就不生成了,那么可以使用default显示指定移动构造生成。
如果不想要某个默认函数生成,只需要在函数声明处加上=delete即可。=delete修饰的函数也称为删除函数。

// 要求delete关键字实现一个类,只能在堆上创建对象
class HeapOnly
{
public:HeapOnly(){_str = new char[10];}~HeapOnly() = delete;void Destroy(){delete[] _str;operator delete(this);}
private:char* _str;
};
void Test9()
{HeapOnly* ptr = new HeapOnly;ptr->Destroy();
}

5. 可变参数模板

相比C++98固定的模板参数,C++11可变参数模板的的引入无疑是一个巨大的改进。

// 一个基本的函数可变参数模板定义
// Args是一个模板参数包,args是一个函数形参参数包,包含有大于等于0个参数
template<class ...Args>
void ShowList(Args... args)
{}

参数args前面有省略号,表示它是一个可变模板参数。把带有省略号的参数称为“参数包”,里面包含了N(N>=0)个模板参数。由于语法不支持使用args[i]这样的方式获取参数,需要使用一些特别的方法来一一获取参数包中的参数。

  1. 递归展开参数包
void ShowList() {} // 递归终止函数template <class T, class ...Args>
void ShowList(const T& val, Args... args)
{cout << "ShowList(" << val << ", " << sizeof...(args) <<"个参数)" << endl;ShowList(args...);
}void Test10()
{ShowList(1, 'A', string("one"));
}

在这里插入图片描述
2. 构建数组展开参数包

template<class T>
int PrintArg(const T& val)
{cout << val << " ";return 0;
}template <class ...Args>
void ShowList(Args... args)
{int a[] = { PrintArg(args)... };cout << sizeof(a) / sizeof(int) << endl;
}void Test11()
{ShowList(1, 'A', string("one"));
}

在这里插入图片描述
{ PrintArg(args)... }将会展开成 { PrintArg(arg1), PrintArg(arg2), PrintArg(arg3), ... },最终会创建一个元素值都为PrintArg返回值的数组。也就是说在构建数组的过程中参数包就展开了,而这个数组构建的目的纯粹就是为了在数组构建的过程中展开参数包。

6. push_back 与 emplace_back

在这里插入图片描述
在这里插入图片描述
push_back 与 emplace_back都是在end位置插入一个值。
可以注意到emplace接口支持可变模板参数,并且使用了万能引用。那么相对传统的插入接口,emplace接口优势到底在哪里呢?
在用法上,emplace支持可变参数,拿到参数后,会自己去创建对象,简化使用。

void Test12()
{vector<pair<int, int>> v;v.push_back(make_pair(1,1));v.push_back({ 2,2 });v.emplace_back(3, 3);
}

在底层上,emplace_back是直接构造,push_back是先构造,再拷贝构造/移动构造。
emplace_back直接构造确实会效率高一点,但实际上emplack_back和push_back的使用效果是差别不大的。

7. lambda表达式

lambda表达式实际是一个匿名函数。
lambda表达式语法:[capture-list](parameters)mutable->return-type{statement}

  • [capture-list]:捕捉列表。捕捉列表能够捕捉上下文中的变量供lambda使用,同时编译器也会根据[]来判断接下来的代码是否为lambda函数。
  • (parameters):参数列表。和普通函数的参数列表使用方式一致。如果不需要传参,()也可以省略。
  • mutable:默认情况下,lambda函数是一个const函数,而mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数列表为空)。
  • ->returntype:返回值类型声明。无返回值时可省略;返回值类型明确的情况下,也可省略,交由编译器自行推导返回值类型。
  • {statement}:函数体。在函数体内可以使用参数列表的参数和捕捉列表捕获的变量。
    从lambda表达式定义中,可以知道参数列表和返回值是可选部分,捕捉列表和函数体是可为空部分。所以最简单的lambda函数是[]{}

7.1. 捕捉列表

  • [var]:表示传值方式捕捉变量var
  • [=]:表示传值方式捕捉父作用域中的所有变量(包括this)
  • [&var]:表示传引用方式捕捉变量var
  • [&]:表示传引用方式捕捉父作用域中的所有变量(包括this)
  • [this]:表示传值方式捕捉this指针
void Test13()
{int x = 1;int y = 2;// 默认捕捉(传值捕捉)的变量不能修改// auto swap2 = [=]auto swap2 = [=]()mutable{int tmp = x;x = y;y = tmp;};swap2();cout << x << " " << y << endl;
}

即使对于传值捕捉的变量进行了修改,也不会对外部实际的变量造成修改。

所谓父作用域是指与lambda所在栈帧平行的栈帧空间。

static int si = 1;
void Test14()
{int i = 2;auto a = [=] {cout << si << endl; cout << i << endl; };a();
}

捕捉列表可由多个项组成,并以逗号分割。

void Test15()
{int a, b, c, d, e;a = b = c = d = e = 1;// 全部传值捕捉auto f1 = [=](){cout << a << b << c << d << e << endl;};f1();cout << a << endl;// 混合捕捉auto f2 = [=, &a](){++a;cout << a << b << c << d << e << endl;};f2();cout << a << endl;auto f3 = [&, a]()mutable{++a;cout << a << b << c << d << e << endl;};f3();cout << a << endl;
}

捕捉列表不允许变量重复传递。比如[=, this],this捕捉会重复,从而导致编译错误。
lambda表达式之间不能相互赋值。

void Test16()
{auto f1 = [] {cout << "hello world"; };auto f2 = [] {cout << "hello world"; };//f2 = f1; // errcout << typeid(f1).name() << endl;cout << typeid(f2).name() << endl;
}

在这里插入图片描述
lambda对象不能相互赋值,本质原因是因为类型不同,不能相互赋值。
这也说明,lambda在使用者角度是匿名的,在底层还是有名的。
实际在底层,编译器对于lambda表达式的处理,完全是按照函数对象的方式处理的。即:如果定义了一个lambda表达式,编译器会自动生成一个类(为其生成lambda_uuid的类型名),在该类中会重载operator()。
在这里插入图片描述

8. function包装器

C++中的function本质是一个类模板。
那为什么要有包装器呢?

template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}
double f(double i)
{return i / 2;
}
struct Functor
{double operator()(double d){return d / 3;}
};void Test17()
{// 函数指针cout << useF(f, 11.11) << endl;// 函数对象cout << useF(Functor(), 11.11) << endl;// lambda表达式对象cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;// 函数指针 | 仿函数/函数对象 | lambda(匿名函数) -> 都能像函数一样被使用
}

在这里插入图片描述
可以发现useF函数模板实例化了三份。但如果使用包装器就可以很好地优化上面的问题。
在这里插入图片描述
Ret:被调用函数的返回类型
Args…:被调用函数的形参

void Test18()
{// 函数指针function<double(double)> f1 = f;cout << useF(f1, 11.11) << endl;// 函数对象function<double(double)> f2 = Functor();cout << useF(f2, 11.11) << endl;// lambda表达式对象function<double(double)> f3 = [](double d)->double {return d / 4; };cout << useF(f3, 11.11) << endl;
}

在这里插入图片描述

8.1. bind

可以把bind看做是函数适配器。bind的作用主要是可以接收一个可调用对象(callable object),同时生成一个新的可调用对象来“适应”原对象的参数列表。使用bind我们可以把一个原本接收 n 个参数的函数 f,通过绑定一些参数,然后返回一个接收 m 个参数的新函数,同时可以做到对参数顺序的调整。
在这里插入图片描述
bind的一般使用形式:auto newCallable = bind(callable, arg_list)
newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应callable的参数。当调用newCallable时,newCallable会调用callable,并传递给它arg_list中的参数。
arg_list中的参数可能包含形如 _n (n 是一个整数)的名字,这些参数是“占位符”,表示newCallable的参数。这些“占位符”占据了传递给newCallable的参数的“位置”。例如,_1为newCallable的第一个参数,_2为第二个参数,…

class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};void Test19()
{function<int(int, int)> f1 = Plus::plusi;function<double(Plus, double, double)> f2 = &Plus::plusd;cout << f1(1, 2) << endl;cout << f2(Plus(), 1.1, 2.2) << endl;// 调整参数个数,绑死固定参数function<int(int, int)> f3 = bind(Plus::plusi, placeholders::_1, placeholders::_2);function<double(double, double)> f4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);cout << f3(1, 2) << endl;cout << f4(1.1, 2.2) << endl;
}

在这里插入图片描述

相关文章:

【C++】C++11常用特性梳理

C11特性梳理 1. 列表初始化2. auto & decltype3. 右值引用3.1. 左右值引用比较3.2. 右值引用的意义3.3. 万能引用与完美转发3.4. 移动构造与移动赋值 4. default & delete5. 可变参数模板6. push_back 与 emplace_back7. lambda表达式7.1. 捕捉列表 8. function包装器8…...

修改iframe生成的pdf的比例

如图想要设置这里的默认比例 在iframe连接后面加上#zoom50即可&#xff0c;50是可以随便设置的&#xff0c;设置多少就是多少比例 <iframe src"name.pdf#zoom50" height"100%" width"100%"></iframe>...

C++之list的用法介绍

C之list的用法介绍 1&#xff09;定义和初始化&#xff1a; #include <list> std::list<int> my_list; // 定义一个整数类型的list std::list<std::string> my_other_list {"apple", "banana", "cherry"}; // 初始化一个…...

Mybatis-plus 内部提供的 ServiceImpl<M extends BaseMapper<T>, T> 学习总结

作用 当集成Mybatis-Plus 后&#xff0c;我们的大部分数据库操作都可以通过 XxxxxMapper &#xff0c;同时 Mybatis-plus 在Mapper 提供基本操作方法的同时&#xff0c;也提供类基础的 serviceImpl 来帮助我们完成一些常见的基本操作。 使用 一般情况下&#xff0c;我们首先…...

yolov5 利用Labelimg对图片进行标注

首先打开yolov5-master&#xff0c;在data文件中新建一个文件夹来存放你需要跑的数据&#xff0c;例如我这次跑的是羽毛球&#xff0c;文件把文件取名为badminton。使用其他文件夹例如images也可以&#xff0c;就是跑多了以后不好整理&#xff0c;然后点击 选中刚刚你存放数据的…...

完整版付费进群带定位源码

看到别人发那些不是挂羊头卖狗肉&#xff0c;要么就是发的缺少文件引流的。恶心的一P 这源码是我付费花钱买的分享给大家&#xff0c;功能完整。 搭建教程 nginx1.2 php5.6--7.2均可 最好是7.2 第一步上传文件程序到网站根目录解压 第二步导入数据库&#xff08;shujuk…...

华为L410上制作内网镜像模板01

原文链接&#xff1a;华为L410上制作离线安装软件模板01 hello&#xff0c;大家好啊&#xff0c;今天给大家带来一篇在内网搭建Apache服务器&#xff0c;用于安装完内网操作系统后&#xff0c;在第一次开机时候&#xff0c;为系统安装软件&#xff0c;今天给大家用WeChat举例&a…...

linuxC语言缓冲区及小程序的实现

文章目录 1.文件缓冲区1.1介绍1.2缓冲文件系统1.3冲刷函数fflush1.4认识linux下的缓冲区 2.linux小程序的实现2.1 回车\r和换行\n2.2倒计时程序2.3进度条小程序sleep/usleep代码运行结果 1.文件缓冲区 1.1介绍 为缓和 CPU 与 I/O 设备之间速度不匹配&#xff0c;文件缓冲区用以…...

MySQL数据库基本操作-DDL 数据库基础知识

目录标题 1、数据库操作1-1 查询所有数据库1-2 创建数据库1-3 选择使用那个数据库1-4 删除数据库 2、数据库表操作2-1 创建数据库表2-2 查看当前数据库所有表名称2-3 查看指定某个表的创建语句2-4 查看表结构2-5 删除表 3、修改表结构格式3-1 修改表添加列3-2 修改列名和类名3-…...

基于JavaWeb+SpringBoot+Vue摩托车商城微信小程序系统的设计和实现

基于JavaWebSpringBootVue摩托车商城微信小程序系统的设计和实现 源码传送入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码传送入口 前言 近年来&#xff0c;随着移动互联网的快速发展&#xff0c;电子商务越来越受到…...

idea代码快捷键Mac版

1、查询任何东西 双击 Shift2、文件内查找 Command F 3、文件内替换 Command R4、全局查找&#xff08;根据路径&#xff09; Command Shift F5、在当前文件跳转到某一行的指定处 Command L6、退回 / 前进到上一个操作的地方 Command Option 方向键左Command Opt…...

分享76个Python管理系统源代码总有一个是你想要的

分享76个Python管理系统源代码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 下载链接&#xff1a;https://pan.baidu.com/s/1JtcEHG9m8ro4-dc29kVyDg?pwd8888 提取码&#xff1a;8888 项目名称 A simpl…...

Springboot养老院信息管理系统的开发-计算机毕设 附源码27500

Springboot养老院信息管理系统的开发 摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;…...

在虚拟机中安装vim和net-tools,mysql

首先在虚拟机中创建vim目录 sudo mkdir -p /home/user/tools/vim然后开始进行安装 yum install vim -yyum install net-toolsmysql参考链接 安装mysql在虚拟机中...

【Excel】函数sumif范围中符合指定条件的值求和

SUMIF函数是Excel常用函数。使用 SUMIF 函数可以对报表范围中符合指定条件的值求和。 Excel中sumif函数的用法是根据指定条件对若干单元格、区域或引用求和。 sumif函数语法是&#xff1a;SUMIF(range&#xff0c;criteria&#xff0c;sum_range) sumif函数的参数如下&#xff…...

k8s上对Pod的管理部分详解

目录 一.Pod结构介绍 1.user container 2.pause 二.Pod工作形式介绍 1.自主式pod 2.控制器管理下的pod 三.对Pod的操作介绍 1.run/apply -f/create -f运行pod 2.get查看pod信息 3.exec操作运行中的pod &#xff08;1&#xff09;进入运行中的pod &#xff08;2&…...

4.4.2 结构可以将 string类作为成员吗

// structure template { }; 4.4.2 结构可以将 string类作为成员吗 可以将成员name指定为string类对象而不是字符数组吗?即可以像下面这样声明结构吗? #include <string> struct inflatable std :: string name; float volume; double price; 大体上说,答案是肯定的。实…...

npm install 安装总结

npm install moduleName 会把moduleName 包安装到node_modules目录中不会修改package.json之后运行npm install命令时&#xff0c;不会自动安装moduleName npm install moduleName -g 安装模块到全局&#xff0c;不会在项目node_modules目录中保存模块包。不会将模块依赖写入de…...

二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理

在前文中&#xff0c;我们介绍了组合模式的基本原理和应用&#xff0c;以及它在构建对象结构中的价值和潜力。然而&#xff0c;组合模式的魅力远不止于此。在本文中&#xff0c;我们将继续探索组合模式的进阶应用&#xff0c;并展示它与其他设计模式的结合使用&#xff0c;以构…...

jenkins分步式构建环境(agent)

rootjenkins:~# netstat -antp|grep 50000 tcp6 0 0 :::50000 ::&#x1f617; LISTEN 5139/java 1.52 安装Jenkins rootubuntu20:~# dpkg -i jenkins_2.414.3_all.deb 配置各种类型的Agent的关键之处在于启动Agent的方式 ◼ JNLP Agent对应着“通过Java Web启动代理”这种方…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...