虚拟显式转换运算符覆盖

phi*_*mue 27 c++ overriding explicit operator-overloading c++11

我有一个类Base定义explicit operator bool:

struct Base {
    virtual explicit operator bool() const {
        return true;
    }
};
Run Code Online (Sandbox Code Playgroud)

我有一个子类Derived,定义operator bool:

struct Derived : Base {
    operator bool() const override {
        return false;
    }
};
Run Code Online (Sandbox Code Playgroud)

正如你可以观察到的那样,Derived::operator bool明确没有标记explicit,但是标记了override,所以我期望编译器抱怨.然而,gcc和clang似乎都同意这是有效的.我的期望不合理吗?

而且,如果我使用如下的类,TakesBool(base)不编译(如预期的那样),但是TakesBool(derived):

void TakesBool(bool b) {}

int main() {
    //Base base;     TakesBool(base); // compilation error (as expected)
    Derived derived; TakesBool(derived);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这似乎表明Derived有一个(非explicit)operator bool,但是,override没有virtual声明就标记了.这怎么可能?

son*_*yao 20

你可能会认为非explicit operator bool在Derived没有覆盖explicit operator bool的Base,不,不.该明确说明符并不重要,它不是函数签名的一部分.

从标准§10.3/ 2虚函数[class.virtual]:

(强调我的)

如果vf在类Base和类中声明虚拟成员函数Derived,直接或间接地从具有相同名称Base的成员函数派生,参数类型列表([dcl.fct]),cv-qualification和ref-qualifier (或不存在的相同)作为被声明,则也虚拟(它是否被如此声明)和它覆盖.vfBase::vfDerived::vfBase::vf

因此,只有当函数的name,parameter-list,cv-qualification或ref-qualifier不匹配时,编译器才会抱怨,不会考虑显式说明符.


你说"标记override没有virtual声明",请注意virtual派生类中成员函数的声明是多余的,它也是virtual.

  • 我调查过,有一个基类同时具有`显式运算符bool`和`运算符bool`,并且这两个基元的处理方式不同.你知道如果派生类定义`operator bool()override`会发生什么?它是否会覆盖`operator bool`s? (2认同)
  • @phimuemue就在那里:`explicit`不是签名的一部分.无论层次结构中的位置如何,都不能声明具有相同签名的2个函数.尝试它会告诉你这个!songyuanyao为Clang展示了同样的东西,这里是GCC:http://coliru.stacked-crooked.com/a/f329d16b4b8ac66b`main.cpp:9:22:错误:'virtual Base :: operator bool()const'不能重载显式虚拟运算符bool()const ^ ~~~~~~~ main.cpp:4:13:错误:用'virtual Base :: operator bool()const'虚拟运算符bool()const ^ ~~~~ ~~~` (2认同)