Первый пример:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const A&) = delete;
A(A&&) = default;
A(const int i) : ref(new int(i)) { }
~A() = default;
};
int main()
{
A a[2] = { 0, 1 };
return 0;
}
Он отлично работает. Итак, здесь используется конструктор MOVE.
Удалите конструктор перемещения и добавьте копию:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const A&a)
: ref( a.ref.get() ? new int(*a.ref) : nullptr )
{ }
A(A&&) = delete;
A(const int i) : ref(new int(i)) { }
~A() = default;
};
int main()
{
A a[2] = { 0, 1 };
return 0;
}
Теперь компиляция падает с ошибкой "использование удаленной функции" A:: A (A & &) "
Поэтому конструктор MOVE НЕОБХОДИМО и не возвращается к конструктору COPY.
Теперь давайте удалим как copy-и move-constructors:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const int i) : ref(new int(i)) { }
~A() = default;
};
int main()
{
A a[2] = { 0, 1 };
return 0;
}
И он падает с "ошибкой компиляции удаленной функции A:: A (const A &)". Теперь он ТРЕБУЕТ конструктора COPY!
Таким образом, резервный (?) От конструктора перемещения был создан конструктором копирования.
Зачем? Кто-нибудь знает, как он соответствует стандарту С++ и каково фактически правило выбора между конструкторами копирования/перемещения?