Хумама Helfawi получил точку.
Я стараюсь завершить его ответ.
Svalorzen: посмотрите на этот код
#include <iostream>
template <typename T>
struct X {
X() : x(5) {}
template <template <typename> class S>
X (const S<T> & y) : x(y.x)
{ std::cout << "templated constructor" << std::endl; }
X (const X<T> & y) : x(y.x)
{ std::cout << "copy constructor" << std::endl; }
T x;
};
int main()
{
X<int> y;
auto x = y;
return 0;
}
Выход "конструктор копирования".
Когда компилятор найдет подходящую шаблонную функцию и соответствующую обычную (без шаблонов) функцию, выберите равнину как более конкретную.
Теперь удалите определение копии застройщика
#include <iostream>
template <typename T>
struct X {
X() : x(5) {}
template <template <typename> class S>
X (const S<T> & y) : x(y.x)
{ std::cout << "templated constructor" << std::endl; }
T x;
};
int main()
{
X<int> y;
auto x = y;
return 0;
}
и вы получите ваш пример без конструктора перемещения и с соиЬ («шаблонный конструктор») добавил.
Вы можете видеть, что выход пуст.
Это потому, что компилятор выбирает контр-копию, который по умолчанию является неявным.
Когда вы добавляете конструктор перемещения, вы случайно отмечаете как удаленный конструктор копирования. Но конструктор копирования всегда присутствует (даже как отмечено как удаленный), и компилятор его рассматривает. Итак, когда компилятор попытается реализовать «x = y», сопоставьте свой шаблонный конструктор, сопоставьте конструктор копирования, выберите конструктор копирования (более конкретный), увидите, что он удален и дает ошибку.
При добавлении
X (const X<T> &) = default;
вы позволяете компилятору использовать конструктор копирования.
p.s .: извините за мой плохой английский.
Рассмотрите возможность размещения ошибки с кодом. – zneak