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

做片头片尾比较好的网站大众网疫情最新消息

做片头片尾比较好的网站,大众网疫情最新消息,有个印度做网站的天天找我,视频类网站开发经验1.基本概念 可变参数模板允许模板函数或模板类接受零个或多个参数。这些参数可以是不同类型的数据。其语法的核心是使用 ...&#xff08;省略号&#xff09;来表示可变参数部分。 2.语法 template <typename... Args> void func(Args... args); typename... Args&#…

1.基本概念

可变参数模板允许模板函数或模板类接受零个或多个参数。这些参数可以是不同类型的数据。其语法的核心是使用 ...(省略号)来表示可变参数部分。

 2.语法

template <typename... Args>
void func(Args... args);
  • typename... Args:表示参数类型列表,Args 是一个类型参数包(parameter pack)。

  • args...:表示参数值列表,args 是一个值参数包(parameter pack)。

  • 使用sizeof...运算符去计算参数包中参数的个数。

 3.完美转发

完美转发是指在模板函数中,能够将参数以完全相同的值类别(lvalue 或 rvalue)传递给目标函数。std::forward 是实现完美转发的关键工具。

3.1为什么需要完美转发?

在模板函数中,参数的类型可能是一个左值引用或右值引用。如果不使用 std::forward,直接将参数传递给目标函数可能会导致类型不匹配或性能问题。

  • 如果直接传递参数,左值引用会被当作左值处理,右值引用会被当作右值处理。

  • 但目标函数可能需要以不同的方式处理左值和右值。

3.2 std::forward 的工作原理

std::forward 的行为取决于模板参数 T 的类型:

  • 如果 T 是一个左值引用类型(T&),std::forward 会将参数作为左值返回。

  • 如果 T 是一个右值引用类型(T&&),std::forward 会将参数作为右值返回。

  • 如果 T 是一个非引用类型(T),std::forward 会根据传入的参数类型决定返回左值还是右值。

 3.3 引用折叠

在C++中,引用折叠是C++11标准引入的一个特性,用于处理引用的引用(例如 T&&)时的类型推导规则。引用折叠的目的是确保引用的引用不会导致复杂的、难以理解的类型,而是会折叠成一个简单的引用类型。它在模板编程和完美转发中非常重要。

3.3.1 引用折叠的规则

引用折叠的规则如下:

  • 两个左值引用T& & 折叠成 T&

  • 左值引用和右值引用T& && 折叠成 T&

  • 右值引用和左值引用T&& & 折叠成 T&

  • 两个右值引用T&& && 折叠成 T&&

  • 总结:左+左=左;左+右=左;右+右=右

3.3.2 代码训练

 判断一下代码哪些会报错(ps:先不要看注释,自己做,结合引用折叠的规则判断函数被实例化成什么,在根据左值右值判断正确与否

// 由于引⽤折叠限定,f1实例化以后总是⼀个左值引⽤
#include<iostream>
using namespace std;
template<class T>
void f1(T& x)
{}// 由于引⽤折叠限定,f2实例化后可以是左值引⽤,也可以是右值引⽤
//如果传入的参数是左值,T&&会折叠为T&,即左值引用。
//如果传入的参数是右值,T&& 保持为T&& ,即右值引用。
template<class T>
void f2(T&&x)
{}int main()
{typedef int& lref;        //左值引用typedef int&& rref;       //右值引用int n = 0;lref& r1 = n;        //左+左=左     // r1 的类型是 int&lref&& r2 = n;       //右+左=左		// r2 的类型是 int&rref& r3 = n;        //右+左=左		// r3 的类型是 int&rref&& r4 = 1;       //右+右=右     // r4 的类型是 int&&//先通过f1f2的定义判断出被实例化成啥,在判断对错// 没有折叠->实例化为void f1(int& x)f1<int>(n);    //因为 n 是一个左值(假设 n 是一个 int 类型的变量),它可以绑定到 int& 上。//f1<int>(0);   这是因为 0 是一个整型字面量,它是一个右值,而 f1<int> 被实例化为 void f1(int& x),它期望的是一个 int 类型的左值引用。在C++中,你不能将一个右值绑定到左值引用上// 折叠->实例化为void f1(int& x)f1<int&>(n);//f1<int&>(0); // 报错//因为 0 是一个右值,不能绑定到 int& 上。// 折叠->实例化为void f1(int& x)f1<int&&>(n);//f1<int&&>(0); // 报错// 折叠->实例化为void f1(const int& x)//字面量可以绑定到 const 左值引用上f1<const int&>(n);f1<const int&>(0);// 折叠->实例化为void f1(const int& x)f1<const int&&>(n);f1<const int&&>(0);// 没有折叠->实例化为void f2(int&& x)//f2<int>(n);f2<int>(0);// 折叠->实例化为void f2(int& x)f2<int&>(n);//f2<int&>(0); // 报错// 折叠->实例化为void f2(int&& x)//f2<int&&>(n); // 报错f2<int&&>(0);return 0;
}

3.4 万能引用

万能引用是一种特殊的引用类型,它在模板参数推导时可以匹配任何类型(左值或右值)。它使用 && 来声明,但是它的行为取决于模板参数的推导结果。

示例:

// 万能引用
template<class T>
void function(T&& t)
{int a = 0;T x = a;//x++;cout << &a << endl;cout << &x << endl << endl;
}
int main()
{// 10是右值,推导出T为int,模板实例化为void Function(int&& t),不折叠function(10);int a;// a是左值,推导出T为int&,引用折叠,模板实例化为void Function(int& t)function(a);// std::move(a)是右值,推导出T为int,模板实例化为void Function(int&& t),不折叠function(move(a));     右值const int b = 8;// b是左值,推导出T为const int&,引用折叠,模板实例化为void Function(const int&t)// const 限定的变量不能被修改,所以Function内部会编译报错,x不能++function(b); // const 左值// std::move(b)右值,推导出T为const int,模板实例化为void Function(const int&&t)// 所以Function内部会编译报错,x不能++function(std::move(b)); // const 右值return 0;
}

 我们可以用forward优化一下

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<class T>
void Function(T&& t)
{// 保持t的属性Fun(forward<T>(t));
}
int main()
{// 10是右值,推导出T为int,模板实例化为void Function(int&& t)Function(10); // 右值int a;// a是左值,推导出T为int&,引用折叠,模板实例化为void Function(int& t)Function(a); // 左值// std::move(a)是右值,推导出T为int,模板实例化为void Function(int&& t)Function(std::move(a)); // 右值const int b = 8;// a是左值,推导出T为const int&,引用折叠,模板实例化为void Function(const int& t)Function(b);// std::move(b)右值,推导出T为const int,模板实例化为void Function(const int&& t)Function(std::move(b)); // const 右值return 0;
}

4. emplace接口

在C++中,emplace系列接口是一组非常有用的函数,它们允许你直接在容器内部构造对象,而不是先构造一个临时对象然后再将其插入容器中。这可以提高效率,特别是当对象的构造函数比较复杂或者需要多个参数时。

4.1 主要特点

  1. 原地构造emplace系列函数直接在容器内部构造对象,避免了额外的复制或移动操作。

  2. 可变参数模板:这些函数通常与可变参数模板一起使用,以便于直接在容器内部就地拷贝对象,而不是通过拷贝构造函数或移动构造函数进行操作。

  3. 性能优化:在某些情况下,使用emplace系列函数可以显著提升性能,尤其是当插入的对象较复杂时。

  4. 代码简洁emplace提供了更简洁的语法,直接传递构造函数的参数,无需显式地创建对象。

  5. 构造方式:传左值,跟push_back一样,走拷贝构造;传右值,跟push_back一样,走移动     构造

  6. 使用方式emplace系列接口的使用方式与容器原有的插入接口的使用方式类似,但又有一些不同之处。例如,emplace_back函数可以接受用于构造元素的参数包。不要再写{}了!!!而push_back()要写,要走initializer_list

 

std::vector<std::pair<int, std::string>> mylist;
mylist.emplace_back(1, "A");

 在这个例子中,我们直接传递了构造std::pair<int, std::string>所需的参数,而不是先创建一个pair对象再将其插入到vector中。

4.2 与push_back的比较

4.2.1 push_back

当使用 push_back 时,如果容器需要更多的空间来存储新元素,可能会触发重新分配内存的操作,这涉及到复制或移动现有元素到新的内存位置,然后添加新元素。push_back 通常需要一个已经构造好的对象作为参数,或者使用拷贝构造函数或移动构造函数来构造新元素。

4.2.2 emplace_back

emplace_back 是 C++11 引入的方法,它允许你直接在容器内部构造新元素,而不需要先构造一个临时对象。使用 emplace_back 可以传递多个参数,这些参数将直接用于构造新元素,从而避免了额外的复制或移动操作。emplace_back 通常用于需要传递多个参数或避免临时对象的场合,特别是在处理大型对象或资源密集型对象时,可以显著提高性能。

4.2.3 性能比较

在大多数情况下,emplace_backpush_back 更有效率,因为它避免了创建和销毁临时对象的开销。当容器需要重新分配内存时,emplace_backpush_back 的性能差异可能不那么明显,因为重新分配的开销占主导地位。

4.2.4 使用场景

使用 push_back: 当你已经有一个构造好的对象,或者当你需要添加的对象的构造函数非常简单时。

使用 emplace_back :当你需要传递多个参数来构造新元素,或者当你希望避免创建临时对象以提高性能时。

http://www.dtcms.com/wzjs/207168.html

相关文章:

  • 19年做网站今日疫情最新情况
  • 可以看女人不易做网站网络推广公司专业网络
  • 最好的网站开发平台如何在百度发布短视频
  • 品质好房seo视频教程汇总
  • 洛阳市住房与城乡建设部网站域名注册查询系统
  • 东莞网站建设主要学什么天津seo数据监控
  • 网站建设管理 优帮云新航道培训机构怎么样
  • 网站规划的原则有哪些指数型基金怎么买
  • 日本做头像的网站有哪些免费网站模板网
  • 鹰潭做网站的什么样的人适合做策划
  • 武汉做网站制作全媒体广告投放平台
  • 建站不备案深圳网站建设推广
  • 公司建推广网站多少钱优化大师apk
  • WordPress主题安全吗长沙百度快速优化排名
  • 全国工厂的网站建设渠道推广有哪些方式
  • 移动网站登录入口广告营销
  • wordpress雪樱主题破解seo网站优化经理
  • 门头沟区专业网站制作网站建设北京seo招聘信息
  • 下载 iis 网站软件开发工具
  • 义乌个人兼职做建设网站公众号seo排名优化
  • diango做的网站怎么用免费二级域名分发网站源码
  • wordpress 手机模板东莞市网络seo推广企业
  • 承包酒席可以做网站吗哈尔滨百度关键词优化
  • 网站设计扁平化discuz论坛seo设置
  • 王者做网站百度站长资源平台
  • 自己如何建设网站厦门网络推广
  • 党风廉政建设漫画网站职业技能培训班
  • 网站建设公司的成本有哪些内容广告平台网站有哪些
  • 中山网站外包搜索引擎的四个组成部分及作用
  • 辽icp备鞍山公司中企动力提供网站建设做企业推广的公司