當前位置:網站首頁>emplace_back 和 push_back 的區別

emplace_back 和 push_back 的區別

2022-01-27 11:16:44 愛好學習的青年人

emplace_back 和 push_back 的區別

C++11 STL

emplace_back 和 push_back

  • 直接插入對象,兩個是沒有區別的

  • 給emplace傳入Test對象構造所需要的參數,直接在容器底層構造對象即可

假設 vector 中元素類型是類類型,那麼 emplace_back() 待添加的元素的類型是類中有參構造的參數類型時,emplace_back() 比 push_back() 少一次移動或拷貝構造函數。而如果添加的元素是類類型的對象時,則和 push_back() 一樣都只會調用一次移動構造函數或一次拷貝構造函數(取决於左值還是右值)。

涉及知識點

萬能引用 / 引用折疊,完美轉發,移動構造函數

源碼均基於 vs2019 平臺 vector 文件

push_back源碼

  • push_back是vector的一個普通成員函數,有2個重載,分別接受左值和右值
template <class _Ty, class _Alloc = allocator<_Ty>>
					...
	void push_back(const _Ty& _Val) {
     // insert element at end, provide strong guarantee
        emplace_back(_Val);
    }

    void push_back(_Ty&& _Val) {
     // insert by moving into element at end, provide strong guarantee
        emplace_back(_STD move(_Val)); // 保持原來的右值
    }

emplace_back源碼

  • 只有一個模板 利用了 引用折疊 + 可變參數模板
  • 進行傳遞時用了完美轉發 —— 保持參數的引用類型
public:
    template <class... _Valty>
    decltype(auto) emplace_back(_Valty&&... _Val) {
    
        // insert by perfectly forwarding into element at end, provide strong guarantee
        auto& _My_data   = _Mypair._Myval2;
        pointer& _Mylast = _My_data._Mylast;
        if (_Mylast != _My_data._Myend) {
    
            return _Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
        }

        _Ty& _Result = *_Emplace_reallocate(_Mylast, _STD forward<_Valty>(_Val)...);
#if _HAS_CXX17
        return _Result;
#else // ^^^ _HAS_CXX17 ^^^ // vvv !_HAS_CXX17 vvv
        (void) _Result;
#endif // _HAS_CXX17
    }

_Emplace_back_with_unused_capacity 和 _Emplace_reallocate 最後都調用了 _Alty_traits::construct 進行構造

版權聲明
本文為[愛好學習的青年人]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201271116437018.html

隨機推薦