網(wǎng)站如何提高權(quán)重做百度推廣怎么做才能有電話
在 C++ 11 STL 容器中,push/insert => emplace 新的方法,push 和 emplace 的區(qū)別在于:
1.?push
??push
通常用于將一個元素添加到容器的末尾(在 std::vector
、std::deque
等序列容器中),或者在關(guān)聯(lián)容器中插入一個鍵值對(如 std::map
或 std::set
)。
std::vector<int> vec;
vec.push_back(10); // 將 10 添加到 vector 的末尾
???????對于關(guān)聯(lián)容器(如 std::map
),push
可能是 insert
的一種實現(xiàn):
std::map<int, std::string> m;
m.insert({1, "one"}); // 插入鍵值對
2.?emplace
? emplace
是 C++11 引入的一個新方法。它的主要優(yōu)點是在容器中直接構(gòu)造元素,而不是先構(gòu)造好對象再將其插入到容器中。這可以避免不必要的復(fù)制或移動操作,從而提高效率。
std::vector<int> vec;
vec.emplace_back(10); // 直接在 vector 的末尾構(gòu)造 10
???????對于 std::map
或 std::set
,emplace
會通過傳遞構(gòu)造函數(shù)的參數(shù)直接構(gòu)造元素(鍵值對),避免了額外的復(fù)制或移動操作:
std::map<int, std::string> m;
m.emplace(1, "one"); // 直接在 map 中構(gòu)造鍵值對
主要區(qū)別:
-
元素構(gòu)造方式:
push
:需要先構(gòu)造元素,然后將它添加到容器中。emplace
:直接在容器內(nèi)部構(gòu)造元素,避免了額外的拷貝或移動。
-
性能:
emplace
?在某些情況下可以比?push
?更高效,因為它避免了不必要的臨時對象創(chuàng)建和拷貝。- 對于簡單類型(如?
int
),這兩者差別不大,但對于復(fù)雜類型,emplace
?可能會帶來性能上的優(yōu)勢。
-
使用的場景:
push
?更常見于將已有對象添加到容器中,尤其是當元素類型比較簡單時。emplace
?更適合在容器中直接構(gòu)造復(fù)雜對象,尤其是在對象構(gòu)造涉及多個參數(shù)時。
總結(jié):
push
?是將已經(jīng)構(gòu)造好的元素添加到容器中。emplace
?是直接在容器中構(gòu)造元素,避免了多余的復(fù)制或移動,通常能帶來更好的性能。
在需要頻繁插入復(fù)雜對象時,emplace
通常是更優(yōu)選擇。
代碼驗證:
class Test
{
public:Test(int a){std::cout << "Test(int)" << std::endl;}Test(int a, int b){std::cout << "Test(int, int)" << std::endl;}Test(const Test& t){std::cout << "Test(const Test&)" << std::endl;}Test(Test&& t){std::cout << "Test(Test&&)" << std::endl;}
};int main()
{Test t1(10);std::vector<Test> v;v.reserve(100);std::cout << "==========================" << std::endl;// 直接插入對象,兩個是沒有區(qū)別的v.push_back(t1);v.emplace_back(t1);std::cout << "==========================" << std::endl;// 直接插入對象,兩個是沒有區(qū)別的v.push_back(Test(20));v.emplace_back(Test(20));std::cout << "==========================" << std::endl;// 給emplace傳入Test對象構(gòu)造所需的參數(shù),直接在容器中進行構(gòu)建即可v.emplace_back(20);v.emplace_back(30, 40);
}
emplace 代碼實現(xiàn):
// 實現(xiàn)容器的空間配置器
template<typename T>
struct MyAllocator
{T* allocate(size_t size){return (T*)malloc(size * sizeof(T));}template<typename... Types>void construct(T* ptr, Types&&... args){new (ptr) T(args...);}
};template<typename T, typename Alloc = MyAllocator<T>>
class vector
{
public:vector(): m_vec(nullptr), m_size(0), m_idx(0){}// 預(yù)留內(nèi)存空間void reserve(size_t size){m_vec = m_allocator.allocate(size);m_size = size;}// push_backvoid push_back(const T& val){m_allocator.construct(m_vec + m_idx, val);idx++;}void push_back(T&& val){m_allocator.construct(m_vec + m_idx, std::move(val));idx++;}template<typename... Types>void emplace_back(Types&&... args){m_allocator.construct(m_vec + m_idx, std::forward<Types>(args)...);m_idx++;}private:T* m_vec;int m_size;int m_idx;Alloc m_allocator;
};