当前位置: 首页 > 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/284306.html

相关文章:

  • 昆明网站建设logovi永州网站seo
  • 网站开发答辩百度极速版下载安装
  • 如何提升网站营销力免费网站软件推荐
  • 政府网站建设背景网站seo策划方案案例分析
  • 企业门户网站费用百度关键词查询排名
  • 医院网站建设最新报价花西子网络营销案例分析
  • wordpress自动原创seo教学
  • 网站栏目设置百度第三季度财报2022
  • redis加速wordpress长沙优化科技
  • 顺德专业网站制作网络推广求职招聘交流群
  • wordpress 微博 链接地址北京seo教师
  • 定制网站建设公司竞价排名适合百度这样的网络平台吗
  • 潍坊做电商的网站建设搜索引擎营销案例有哪些
  • 山东德州如何网站建设教程常用的网络推广方式有哪些
  • 长沙市师德师风建设网站浏览器大全
  • 网站转回国内北京谷歌seo
  • 免费建造公司网站免费发广告的网站
  • 展示型企业网站制作费用百度推广工具
  • 做旅游网站一年能挣多少app推广赚钱平台
  • 移动互联网开发技术是什么win7优化教程
  • 品牌广告站内seo是什么意思
  • 杭州网站网站建设四川seo选哪家
  • 网站代码怎么写安徽网站优化
  • 天津电商网站制作全渠道营销
  • 芜湖先锋网站两学一做google推广seo
  • 站群系统的优劣创新营销方式有哪些
  • 彩票真人网站建设百度帐号管家
  • wordpress 非插件七牛cdn全站加速竞价是什么意思
  • 网站主页模板图片网站优化方案设计
  • 泉州免费做网站郑州网站网页设计