Код не является законным.
i = j
вызывает неявно определенный оператор назначения копирования в MyClass
. Эта функция вызывает оператор присваивания для каждого из его подобъектов, включая прямые базовые классы [class.copy 12.8 p28].
Если вы добавите код в оператор назначения копирования для BaseClass, вы увидите, где VS работает неправильно:
template<typename T>
BaseClass& operator= (const T& a_other)
{
std::cout << typeid(T).name() << '\n';
int i = 0; // for break point
return *this;
}
Для меня это выводит "struct MyClass". VS вызывает оператор присваивания BaseClass
, передавая параметр, полученный непосредственно в MyClass:operator=
, а не только субобъект BaseClass
в j.
SFINAE не вступает в игру, потому что функции шаблонов не работают. VS просто неправильно генерирует оператор неявного копирования.
Подводя итог:
VS генерирует неявный оператор присваивания копии как
MyClass &operator=(const MyClass& rhs) {
static_cast<BaseClass&>(*this).operator=(rhs);
return *this;
}
Когда это должно быть:
MyClass &operator=(const MyClass& rhs) {
static_cast<BaseClass&>(*this).operator=(static_cast<const BaseClass&>(rhs));
return *this;
}