c – 由于右值参考向量:: push_back函数如何提高效率而感到困惑

c – 由于右值参考向量:: push_back函数如何提高效率而感到困惑,第1张

概述在cppreference.com上,我找到了一个关于使用std :: move的简单示例: std::string str = "Hello";std::vector<std::string> v;// uses the push_back(const T&) overload, which means // we'll incur the cost of copying strv.p 在cppreference.com上,我找到了一个关于使用std :: move的简单示例:

std::string str = "Hello";std::vector<std::string> v;// uses the push_back(const T&) overload,which means // we'll incur the cost of copying strv.push_back(str);                                    // First push_backstd::cout << "After copy,str is \"" << str << "\"\n";// uses the rvalue reference push_back(T&&) overload,// which means no strings will be copIEd; instead,the contents// of str will be moved into the vector.  This is less// expensive,but also means str might Now be empty.v.push_back(std::move(str));                        // Second push_back

评论说避免了字符串拷贝.

第一个push_back将调用:voID push_back(const value_type& _Val)

第二个push_back将调用:voID push_back(value_type&& _Val)

我检查了两个函数的实现代码:

voID push_back(const value_type& _Val)    {   // insert element at end    if (_InsIDe(_STD addressof(_Val)))        {   // push back an element        size_type _IDx = _STD addressof(_Val) - _Unfancy(this->_Myfirst());        if (this->_Mylast() == this->_Myend())            _Reserve(1);        _Orphan_range(this->_Mylast(),this->_Mylast());        this->_Getal().construct(_Unfancy(this->_Mylast()),this->_Myfirst()[_IDx]);        ++this->_Mylast();        }    else        {   // push back a non-element        if (this->_Mylast() == this->_Myend())            _Reserve(1);        _Orphan_range(this->_Mylast(),_Val);        ++this->_Mylast();        }    }

voID push_back(value_type&& _Val)    {   // insert by moving into element at end    if (_InsIDe(_STD addressof(_Val)))        {   // push back an element        size_type _IDx = _STD addressof(_Val) - _Unfancy(this->_Myfirst());        if (this->_Mylast() == this->_Myend())            _Reserve(1);        _Orphan_range(this->_Mylast(),_STD forward<value_type>(this->_Myfirst()[_IDx]));        ++this->_Mylast();        }    else        {   // push back a non-element        if (this->_Mylast() == this->_Myend())            _Reserve(1);        _Orphan_range(this->_Mylast(),_STD forward<value_type>(_Val));        ++this->_Mylast();        }    }

所以,根据我的理解,第一个push_back(v.push_back(str);)和第二个push_back(v.push_back(std :: move(str));)都会触发向量来构造一个std :: string类型的变量并将其附加到矢量.

因此,实际上在两个push_back调用中,都没有复制字符串.并且,对于两个push_back,费用是相同的,因为两个调用基本上做同样的事情,除了第二个push_back将使str输入为空.

至于效率,我能想到的唯一区别是第二个push_back不会调用delete [] cstring;在std :: string的析构函数中,它使第二个push_back调用更有效率.

不确定我的理解是否正确.非常感谢!

解决方法 区别在于:

this->_Getal().construct(_Unfancy(this->_Mylast()),_STD forward<value_type>(_Val));

VS

this->_Getal().construct(_Unfancy(this->_Mylast()),_Val);

现在转发< value_type>实际上在std :: string上调用std :: move.

在一种情况下,我们用std :: string const&和std :: string&&来构造一个std :: string.

所以为了看到差异,我们必须检查这两个不同构造函数的作用.

std :: string通常用SBO实现(小缓冲区优化).如果字符串很短(十几个字符),则字符串存储在std :: string中.

如果它更长,则std :: string存储指向它的指针.

如果SBO处于活动状态,则移动和复制将字节复制过来.然后移动可以清除源.

在非SBO的情况下,std :: string(std :: string const&)执行分配并复制包含字符的缓冲区.

在非SBO的情况下,std :: string(std :: string&&)将指针移动到目标对象,并清空源对象.不进行内存分配,并复制零字节.

这就是push_back(&& amp;)重载提供的内容.

总结

以上是内存溢出为你收集整理的c – 由于右值参考向量:: push_back函数如何提高效率而感到困惑全部内容,希望文章能够帮你解决c – 由于右值参考向量:: push_back函数如何提高效率而感到困惑所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1217674.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存