I know, say, for an std::vector, push_back(x) means to copy or move x to the end of the vector and emplace_back(x) means to construct x at the end of the vector but can't understand that difference well!
Could you explain that a little more (and if there's also some code used for both to demonstrate their difference, it will be more appreciated)?
For a non-trivial type, emplace_back() (construct in-place) is obviously faster than creating an object first and then copy constructing it into the vector. (when reallocation does dot take place). Depending on how efficient the move is, and how clever the optimiser is, emplace_back() may not be significantly faster than constructing a temporary object and then move constructing it into the vector.
For a non-trivial type, emplace_back() (construct in-place) is obviously faster than creating an object first and then copy constructing it into the vector. (when reallocation does dot take place). Depending on how efficient the move is, and how clever the optimiser is, emplace_back() may not be significantly faster than constructing a temporary object and then move constructing it into the vector.
What do you mean by a non-trivial type?
And, what does constructing in place mean, please?
By non-trivial, I meant a type which has some measurable overhead for construction and copy.
I should have used different terminology to avoid confusion; the standard is stricter:
A trivial class is a class that is trivially copyable and has one or more eligible default constructors, all of which are trivial. https://eel.is/c++draft/class.prop#2
> And, what does constructing in place mean, please?
It means construct the object directly in the storage allocated by the vector instead of creating an object outside the vector and then copying/moving it into the storage allocated by the vector.
#include <iostream>
#include <vector>
int main()
{
struct A
{
A( int i, double d ) : i(i), d(d) { std::cout << "constructed object at address " << this << '\n' ; }
A( const A& that ) : i(that.i), d(that.d)
{
std::cout << "copy constructed object at address " << this
<< " (from object at address " << std::addressof(that) << ")\n" ;
}
// ...
int i ;
double d ;
};
std::vector<A> vec ;
vec.reserve(10) ;
// construct a temporary A and copy it into the vector
vec.push_back( A(1,2.3) ) ;
// constructed object at address aaaaaaaa
// copy constructed object at address bbbbbbbb (from object at address aaaaaaaa)
std::cout << "object added is in the vector at address " << std::addressof( vec.back() ) << '\n' ;
// object added is in the vector at address 0x16ce8301ac0
std::cout << '\n' ;
// construct A in-place in the vector
vec.emplace_back(4,5.6) ;
// constructed object at address cccccccc
std::cout << "object added is in the vector at address " << std::addressof( vec.back() ) << '\n' ;
// object added is in the vector at address cccccccc
}