Следующий код (см. этот вопрос ) приводит к ошибке при компиляции с gcc 8.2, но принимается clang 7.0.0 и msvc 15.9.0 preview 3:
template<typename T>
struct B
{
void operator=(const T&) { }
void foo() { }
};
struct D : public B<D>
{
using B<D>::operator=;
using B<D>::foo; // hidden by D::foo
void foo() { }
};
int main()
{
D d1, d2;
d1 = d2;
d1.foo();
return 0;
}
Сообщение об ошибке , сгенерированное gcc :
<source>: In function 'int main()':
<source>:8:8: error: 'constexpr D& D::operator=(const D&)' cannot be overloaded with 'void B<T>::operator=(const T&) [with T = D]'
struct D : public B<D>
^
<source>:4:8: note: previous declaration 'void B<T>::operator=(const T&) [with T = D]'
void operator=(const T&) { }
^~~~~~~~
У нас есть два оператора присваивания в D
, первый из которых генерируется по умолчанию,второй вводится с using
.Они имеют одинаковую подпись, поэтому перегрузка не выполняется.Но почему operator=
из базового класса просто не скрыт классом в производном, как это происходит с foo()
функцией-членом?
Что здесь происходит?Почему только GCC жалуется?Стоит ли жаловаться?