在 GCC 4.6 中,即使子项的赋值运算符由于 move 构造函数而被隐式删除,也可以继承父项的赋值运算符。在更高版本的 GCC(以及 Clang)中,这不再是可能的。让子类使用父类的赋值运算符的正确方法是什么?
struct A
{
A & operator=(A const & other) = default;
};
struct B : public A
{
B() {}
B(B && other) {}
using A::operator=;
};
int main()
{
B b1, b2;
b1 = b2; // error: use of deleted function because B's operator= is implicitly deleted due to move constructor
return 0;
}
最佳答案
被删除的函数仍然声明,只有定义被删除。在您的类定义中扩展它:
struct B : A {
using A::operator=; // A& operator=(const A&)
B& operator=(const B&) = delete;
};
此时,您可以注意到派生类型中有两个 operator=
声明,第一个(通过 using-declaration) 采用 const A&
参数,而第二个采用 const B&
并且被删除。
当您稍后尝试作业时:
B b1, b2;
b1 = b2;
两个声明都被编译器看到,第二个是更好的匹配。因为它被标记为已删除,所以您会收到错误消息。另一方面,如果您分配了一个 A
对象,它将按预期工作:
B b1, b2;
b1 = static_cast<A&>(b2); // works, BUT...
这种方法的问题在于它只复制了可能不是您想要的基础子对象。如果您只想要与编译器生成赋值时相同的行为,您需要请求它:
struct B : A {
// ...
B& operator=(const B&) = default;
};
关于c++ - 隐式删除子项时继承父项赋值运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15752650/