P<T>& operator=(P<T>&& other) noexcept
Это явный оператор назначения перемещения для этого класса шаблона.
struct S : public P<S> {
Этот подкласс наследует от этого класса шаблона. P<S>
является его родительским классом.
У этого подкласса нет явного оператора присваивания перемещения, поэтому ваш компилятор C ++ с готовностью создает для вас оператор присваивания перемещения по умолчанию, потому что именно так работает C ++. Оператор присваивания перемещения по умолчанию вызывает оператор присваивания перемещения родительского класса, а оператор присваивания перемещения по умолчанию затем назначает перемещение всем членам этого класса.
Просто потому, что у родительского класса есть явный оператор присваивания перемещения (ваш ход оператор присваивания) не делает этим оператор присваивания перемещения дочернего класса по умолчанию исчезает. Оператор присваивания перемещений по умолчанию S
по сути таков, очень , говоря свободно:
S &operator=(S &&other)
{
P<S>::operator=(std::move(other));
this->m_val=std::move(other.m_val);
return *this;
}
Это то, что вы получаете бесплатно от своего компилятора C ++. Разве не приятно, что ваш компилятор C ++ предоставляет такой полезный оператор присваивания перемещений по умолчанию для вашего класса?
a = std::move(b);
Это фактически приводит к вызову вышеуказанного оператора присвоения перемещений по умолчанию.
Какой сначала вызывает оператор присваивания перемещения родительского класса, тот, который вы написали.
, который фактически устанавливает other.m_val
в '0'
.
И когда он возвращается, этот оператор присваивания перемещения по умолчанию также устанавливает this->m_val
до '0'
.