Рассмотрим этот код:
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
- в первом случае, но не во втором?