Reputation: 20780
Considering this quote from en.cppreference.com regarding std::vector::emplace_back
"Appends a new element to the end of the container. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element is called with exactly the same arguments that are supplied to the function."
and following sample:
#include <vector>
struct A
{
A(int){}
A(A const&) = delete;
};
int main()
{
std::vector<A> vec;
vec.emplace_back(1);
return 0;
}
On line vec.emplace_back(1);
Visual Studio 2013/GCC report:
error C2280: 'A::A(const A &)' : attempting to reference a deleted function
error: use of deleted function ‘A::A(const A&)’
Is the error correct? Can you please explain me why?
Upvotes: 14
Views: 4829
Reputation: 279255
Like other functions that increase the size of the vector, emplace_back
conditionally reallocates the vector (if the current capacity is not large enough). If it does this then it needs to get the existing elements from the old array to the new.
Your class has no move constructor (some classes have a compiler-generated move, but not this one because you deleted the copy constructor). So the reallocation code needs to be able to copy the type, and it can't.
Of course for this call there are no old elements to copy, but nevertheless the emplace_back
function can't be instantiated.
Upvotes: 7
Reputation: 171127
C++11 23.2.1 Table 101 states:
Expression:
a.emplace_back(args)
Return type:
void
Operation semantics: Appends an object of type
T
constructed withstd::forward<Args>(args)...
. Requires:T
shall beEmplaceConstructible
intoX
fromargs
. Forvector
,T
shall also beMoveInsertable
intoX
.
Your A
does not fulfill the MoveInsertable
requirement, since you do not have a move constructor, and only have a deleted copy constructor. With a container other than std::vector
, it works.
Upvotes: 14