自学内容网 自学内容网

神奇的可变模板参数的应用(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._姓名);
} 

}

输出结果:


原文地址:https://blog.csdn.net/weixin_42944928/article/details/142447378

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!