以下代码(请参见this question)在由gcc 8.2编译时会导致错误,但被clang 7.0.0和msvc 15.9.0预览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;
}
错误消息generated by 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抱怨?应该抱怨吗?