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

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


/// <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 _Where
        size_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._姓名);
	}	 

}

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值