神奇的可变模板参数的应用(C++标准库双向链表 list 中的emplace函数实现)

devtools/2024/10/18 14:24:24/

我们先来看一个可以构造任意对象的函数:


/// <summary>
/// 可以构造任意对象的函数
/// </summary>
/// <typeparam name="MyClass">要转换对象的类型</typeparam>
/// <typeparam name="...MyClassConstructorParameterTypes">转换对象的构造函数参数类型</typeparam>
/// <param name="...MyClassConstructorParameters">转换对象的构造函数参数</param>
/// <returns>返回一个对象</returns>
/// 创建时间: 2024-09-23      最后一次修改时间:2024-09-23
template <class MyClass, typename... MyClassConstructorParameterTypes>
MyClass ConverTo(MyClassConstructorParameterTypes&&... MyClassConstructorParameters)
{ return MyClass(std::forward<MyClassConstructorParameterTypes>(MyClassConstructorParameters)...);
}

例子:

class 学生 : public _Object
{
private:string _姓名;string _性别;
public:学生(string 姓名, string 性别) : _姓名(姓名), _性别(性别) {}
};int main() {auto v1 = ConverTo<int>(1);auto v2 = ConverTo<学生>("碧海蓝天", "男");auto v3 = ConverTo<_string>("123");auto v4 = ConverTo<double>(5.5);vector<int> vec;auto v5 = ConverTo<vector<int>>(vec);}

下面是list::emplace源代码:

    template <class... _Valty>_Nodeptr _Emplace(const _Nodeptr _Where, _Valty&&... _Val) { // insert element at _Wheresize_type& _Mysize = _Mypair._Myval2._Mysize;if (_Mysize == max_size()) {_Xlength_error("list too long");}_List_node_emplace_op2<_Alnode> _Op{_Getal(), _STD forward<_Valty>(_Val)...};++_Mysize;return _Op._Transfer_before(_Where);}

现在它可以这样用:

list<学生> lstu1;lstu1.emplace_back("碧海蓝天", "男");

相当于:

	list<学生> lstu1;lstu1.push_back(学生("碧海蓝天", "男"));

因此,我们与可以写一个_DList 的 emplace_back:

    /// <summary>/// /// </summary>/// <typeparam name="..._Valty"></typeparam>/// <param name="..._Val"></param>/// <returns></returns>/// 创建时间: 2024-09-23      最后一次修改时间:2024-09-23  (已测试)template <class... _Valty>decltype(auto) emplace_back(_Valty&&... _Val) {return this->push_back( T( std::forward<_Valty>(_Val)...) );}

下面来看例子效果:

class 学生 : public _Object
{
public:string _姓名;string _性别;
public:学生(string 姓名, string 性别) : _姓名(姓名), _性别(性别) {}学生() {}
};int main() {list<学生> lstu1;_DList<学生> lstu2;lstu1.emplace_back("碧海蓝天", "男");lstu2.emplace_back("碧海蓝天", "男");for (auto& s : lstu1) {_pn(s._姓名);}for (auto& s : lstu2) {_pn(s._姓名);}	 }

输出结果:


http://www.ppmy.cn/devtools/117436.html

相关文章

用Python实现运筹学——Day 3: 线性规划模型构建

一、学习内容 线性规划模型构建的步骤与技巧 线性规划&#xff08;Linear Programming, LP&#xff09;模型构建是运筹学中的核心内容&#xff0c;通常用于求解资源的最优分配问题。要从实际问题中提取出一个线性规划模型&#xff0c;需要按照以下步骤进行&#xff1a; 问题描…

怎么删除右键出现的Open Folder as Intellij IDEA Project

首先&#xff0c;WinR 输入 regedit &#xff08;注册表编辑器&#xff09;&#xff0c;然后按Enter。 1.右键单击文件夹背景时&#xff08;出现的情况&#xff09;&#xff1a; 在注册表中打开“ 计算机 \ HKEY_CLASSES_ROOT \ Directory \ Background \ shell \ IDEA Commun…

逆概率加权(R和Python案例)

逆概率加权&#xff08;Inverse Probability Weighting, IPW&#xff09;是一种统计技术&#xff0c;用于观察性研究中调整混杂变量的影响&#xff0c;以便更准确地估计因果关系。这种方法特别有用于在无法进行随机化实验的情况下&#xff0c;通过给予不同个体不同的权重&#…

Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题

背景 因为组员对于 Electron 打包过程存在比较迷糊的状态&#xff0c;且自己也没主动探索 Electron-vue 打包细节&#xff0c;导致每次打包过程都消耗 5-6 分钟的时间&#xff0c;在需要测试生产打包时&#xff0c;极其浪费时间&#xff0c;为此针对 Electron-vue 打包的几个环…

JVM基本组成

目录 JDK\JRE\JVM 架构 Java执行流程 工作原理 类型 优点 缺陷 JDK\JRE\JVM JDK:全称“Java Development Kit”&#xff0c;Java开发工具包&#xff0c;提供javac编译器jheap、jconsole 等监控工具&#xff1b;JRE:全称“Java Runtime Environment”&#xff0c;Java 运…

MySQL练手题--获得最近第二次的活动(困难)

一、准备工作 Create table If Not Exists UserActivity (username varchar(30), activity varchar(30), startDate date, endDate date); Truncate table UserActivity; insert into UserActivity (username, activity, startDate, endDate) values (Alice, Travel, 2020-02-…

java基础(3)数组的定义与使用

目录 1.前言 2.正文 2.1数组的概念 2.2数组的创建与初始化 2.2.1数组的创建 2.2.1数组的静态初始化 2.2.2数组的动态初始化 2.3数组是引用类型 2.3.1引用类型与基本类型区别 2.3.2认识NULL 2.4二维数组 2.5数组的基本运用 2.5.1数组的遍历 2.5.2数组转字符串 2.…

【Linux】 tcp | 解除服务器对tcp连接的限制 | 物联网项目配置

一、修改tcp连接限制 1、编辑 vi /etc/sysctl.conf 2、内容 net.ipv4.tcp_keepalive_intvl 75 net.ipv4.tcp_keepalive_probes 9 net.ipv4.tcp_keepalive_time 7200 net.ipv4.ip_local_port_range 1024 65535 net.ipv4.ip_conntrack_max 20000 net.ipv4.tcp_max_tw_bucket…