Reputation: 13398
I have a type that I have deleted the copy constructor from, and I would like to have a vector
of this type, so I need to create all the elements via emplace_back
. But, emplace_back
seems to require a copy constructor, as the compiler gives a warning about not being able to instantiate emplace_back
because the copy constructor has been deleted. Why does it need a copy constructor? I thought the whole point of emplace_back
was to build the vector
without copying anything. Can I even have a vector
of objects that don't have a copy constructor?
class MyType {
public:
MyType(std::array<double, 6> a) {}
MyType(const MyType& that) = delete;
};
int main() {
std::vector<MyType> v;
std::array<double, 6> a = {1,2,3,4,5,6};
v.emplace_back(a);
}
Compiler is clang/llvm.
Upvotes: 22
Views: 8086
Reputation: 19767
When the vector
's internal storage grows, it will need to move the elements from the old storage to the new. By deleting the copy constructor, you also prevent it generating the default move constructor.
Upvotes: 35
Reputation: 20264
If you try to run this code:
// Example program
#include <iostream>
#include <string>
#include <array>
#include <vector>
class MyType {
public:
MyType(std::array<double, 6> a) {
std::cout<< "constructed from array\n";
}
MyType(const MyType& that){
std::cout<< "copy\n";
}
MyType(MyType&& that){
std::cout<< "move\n";
}
};
int main() {
std::vector<MyType> v;
std::array<double, 6> a = {1,2,3,4,5,6};
v.emplace_back(a);
}
You will get the following result:
constructed from array
It is clear that just the constructor
from std::Array
is called. So, no need for copy constructor
. But in the same time if you deleted
the copy constructor
, the compiler will raise an error (at least on two compilers I tried first second ). I think that some compilers will check for the existence of copy constructor
when using emplace_back even if it is not necessary in this practical case while others won't. I do not know what is standard here (which compiler is right or wrong).
Upvotes: 2
Reputation: 4835
To be able to call emplace_back, your type should either be EmplaceConstructible or MoveInsertible . You need to give a move constructor to your class if you have deleted the copy constructor. (Check this for requirements of emplace_back)
MyType(MyType &&a) {/*code*/} //move constructor
Upvotes: 12