Ответ 1
По мере роста внутреннего хранилища vector
необходимо будет переместить элементы из старого хранилища в новое. Удаляя конструктор копирования, вы также не позволяете ему создавать конструктор перемещения по умолчанию.
У меня есть тип, из которого я удалил конструктор копирования, и хотел бы иметь vector
этого типа, поэтому мне нужно создать все элементы с помощью emplace_back
. Но для emplace_back
требуется конструктор копирования, поскольку компилятор дает предупреждение о невозможности создания экземпляра emplace_back
, поскольку конструктор копирования был удален. Зачем нужен конструктор копирования? Я думал, что цель emplace_back
заключалась в создании vector
без копирования чего-либо. Могу ли я даже vector
объектов, у которых нет конструктора копирования?
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);
}
Компилятор - clang/llvm.
По мере роста внутреннего хранилища vector
необходимо будет переместить элементы из старого хранилища в новое. Удаляя конструктор копирования, вы также не позволяете ему создавать конструктор перемещения по умолчанию.
Чтобы иметь возможность вызвать emplace_back, ваш тип должен быть EmplaceConstructible или MoveInsertible. Вам нужно предоставить конструктор перемещения для вашего класса, если вы удалили конструктор копии. (Проверьте этот для требований emplace_back)
MyType(MyType &&a) {/*code*/} //move constructor
Если вы попытаетесь запустить этот код:
// 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);
}
Вы получите следующий результат:
построенный из массива
Понятно, что вызывается только constructor
из std::Array
. Поэтому нет необходимости в copy constructor
. Но в то же время, если вы deleted
copy constructor
, компилятор поднимет ошибку (по крайней мере, на двух компиляторах я попробовал сначала second). Я думаю, что некоторые компиляторы будут проверять существование copy constructor
при использовании emplace_back, даже если это не нужно в этом практическом случае, а другие - нет. Я не знаю, что здесь стандартно (какой компилятор прав или не прав).