含protected相等运算符的派生类默认==运算符被删除问题
基类protected运算符导致派生类默认实现被删除的问题
先看这段可正常编译运行的代码:
class A { protected: bool operator==(const A&) const = default; }; class B : public A { public: bool operator==(const B& b) const { return A::operator==(b); }; }; int main() { B x, y; x == y; }
这段代码在GCC 12.1和Clang 14.0中均可正常运行。根据C++标准,类可以将operator==定义为默认实现,它会按声明顺序逐个比较基类和成员子对象,一旦发现不等就短路返回。
但如果尝试把B类的operator==替换为默认实现,会直接编译失败:
class A { protected: bool operator==(const A&) const = default; }; class B : public A { public: bool operator==(const B& b) const = default; }; int main() { B x, y; // 在Clang和GCC中均编译失败 // error: use of deleted function 'constexpr bool B::operator==(const B&) const' // x == y; x == y; }
当运算符的默认实现存在非法逻辑时,会被编译器隐式删除。问题根源在于:默认实现会在基类A的上下文里调用A::operator==(大致通过std::static_cast<A>(*this) == b这类方式),而该运算符是protected权限,这种跨上下文的调用属于非法操作;但在B的成员函数内显式调用A::operator==却是合法的。
编译器具体报错信息如下:
<source>:8:10: note: 'constexpr bool B::operator==(const B&) const' is implicitly deleted because the default definition would be ill-formed: 8 | bool operator==(const B& b) const = default; | ^~~~~~~~ <source>:8:10: error: 'bool A::operator==(const A&) const' is protected within this context <source>:3:10: note: declared protected here 3 | bool operator==(const A&) const = default;
我们的需求是禁止基类的操作,但允许派生类按需实现,目前可行的变通方案是使用自由函数版本的operator==:
class A { protected: bool operator==(const A&) const = default; }; class B : public A {}; bool operator==(const B& lhs, const B& rhs) { return static_cast<const A&>(lhs) == static_cast<const A&>(rhs); } int main() { B x, y; x == y; // 正常编译 }
内容的提问来源于stack exchange,提问作者OneRaynyDay
相关产品推荐
相关产品推荐

