
Why emplace_back is faster than push_back?
-
since C++ 11 until C++17
12template<class... >void emplace_back(&&... args); -
since C++17
12template<class... >reference emplace_back(&&... args);
Appends a new element to the end of the container. The element is constructed through std::allocator_traits::construct, which typically uses placement-new to construct the element in-place at the location provided by the container. The arguments args… are forwarded to the constructor as std::forward<Args>(args)....
就地构造
If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.
Parameters:
args: arguments to forward to the constructor of the element
Type requirements
T (the container’s element type) must meet the requirements of MoveInsertable and EmplaceConstructible.
Return value
- (none) (until C++17)
- A reference to the inserted element. (since C++17)
Complexity
Amortized constant.
Exceptions
If an exception is thrown, this function has no effect (strong exception guarantee). If T’s move constructor is not noexcept and is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.
如果 move constructor is not noexcept,在发生空间不足需要扩容时,编译器会调用拷贝构造函数而不是移动构造函数,就是为了保证强的异常安全性。
Notes
Since reallocation may take place, emplace_back requires the element type to be MoveInsertable for vectors.
The specialization std::vector<bool> did not have emplace_back() member until C++14.
Example
The following code uses emplace_back to append an object of type President to a std::vector. It demonstrates how emplace_back forwards parameters to the President constructor and shows how using emplace_back avoids the extra copy or move operation required when using push_back.
|
|
Output:
|
|
Note from stack overflow
push_back takes a container element and copies/moves it into the container. emplace_back takes arbitrary arguments and constructs from those a new container element. But if you pass a single argument that’s already of element type to emplace_back, you’ll just use the copy/move constructor anyway.
|
|
The key difference, however, is that emplace_back performs explicit conversions:
|
|
由于 unique_ptr 的构造函数是 explicit 的,即不允许隐式类型转换,所以从 raw pointer 到 unique pointer 的转换是显式的,其实也就是 in-place 构造。
其实上面这个例子更推荐的做法是,
|
|
即通过 make_unique 从可变参数实例化出一个 Foo 对象,并实例化出一个 unique_ptr 对象指向它,并将 unique_ptr 对象移动构造到向量中。
emplace_back 的另外一个优雅用处是:
|
|




近期评论