Рассмотрим этот код:
struct A; // incomplete type
template<class T>
struct D { T d; };
template <class T>
struct B { int * p = nullptr; };
int main() {
B<D<A>> u, v;
u = v; // doesn't compile; complain that D<A>::d has incomplete type
u.operator=(v); // compiles
}
Демо. Поскольку u.operator=(v) компилируется, но u = v; не имеет места, где-то во время разрешения перегрузки для последнего выражения компилятор должен иметь неявно созданный экземпляр D<A> - но я не понимаю, почему требуется эта инстанция.
Чтобы сделать вещи более интересными, этот код компилируется:
struct A; // incomplete type
template<class T>
struct D; // undefined
template <class T>
struct B { int * p = nullptr; };
int main() {
B<D<A>> u, v;
u = v;
u.operator=(v);
}
Демо.
Что здесь происходит? Почему u = v; вызывает неявное создание экземпляра D<A> - типа, который нигде не используется в теле определения B - в первом случае, но не во втором?