У меня есть следующий образец:Что вызывает конструктор перемещения для удаления
#include <vector>
class noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
noncopyable(noncopyable&&) = default;
noncopyable& operator=(noncopyable&&) = default;
};
class C1 : private noncopyable {
public:
C1() { }
~C1() { }
};
int main() {
std::vector<C1> v;
v.emplace_back();
return 0;
}
Я думал, что это должно работать, так как C1
должен быть подвижным, так как это базовый класс и не имеет элементов данных. Вместо этого я получил ошибки (с помощью лязга ++):
error: call to implicitly-deleted copy constructor of 'C1'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
.
.
.
note: in instantiation of function template specialization 'std::vector<C1, std::allocator<C1> >::emplace_back<>' requested here
v.emplace_back();
^
note: copy constructor of 'C1' is implicitly deleted because base class 'noncopyable' has a deleted copy constructor
class C1 : private noncopyable {
^
note: 'noncopyable' has been explicitly marked deleted here
noncopyable(const noncopyable&) = delete;
Делая небольшое исследование (http://en.cppreference.com/w/cpp/language/move_constructor) показали, что если существует определенного пользователь деструктор, то нет неявного шага-конструктор не будет определен. Это, кажется, проблема здесь, поскольку C1
имеет деструктор, конструктор move не определяется. Конечно, если я либо удалю деструктор, либо добавлю C1(C1&&) = default;
в C1
, тогда он будет работать.
Пока все хорошо.
Проблема заключалась в том, что в сообщении об ошибке не упоминалось ~C1()
или конструктор move. Он сказал, что пытается вызвать конструктор копирования, который был удален в базовом классе. Поэтому я попытался изменить функции delete
ed в noncopyable
вместо default
ed и (сюрприз!), Который также решил ошибку.
Итак, мой вопрос в том, что делает последнее, что связано с ошибкой или ее исправлением? Если есть деструктор, в чем разница, если базовый класс имеет экземпляр-конструктор или нет?
Попробуйте добавить спецификатор noexcept. – LogicStuff
Обратите внимание, что существует разница между «не имеет конструктора перемещения» и «имеет конструктор удаленных перемещений». – aschepler