phimuemue phimuemue - 3 months ago 18
C++ Question

Virtual explicit conversion operator overloading

I have a class

Base
defining an
explicit operator bool
:

struct Base {
virtual explicit operator bool() const {
return true;
}
};


And I have a subclass
Derived
, defining an
operator bool
:

struct Derived : Base {
operator bool() const override {
return false;
}
};


As you can observe,
Derived::operator bool
is explicitly not marked
explicit
, but marked
override
, so I expected the compiler to complain. However, both gcc and clang seem to agree that this is valid. Was my expectation unreasonable?

Moreover, if I use the classes as follows,
TakesBool(base)
does not compile (as expected), but
TakesBool(derived)
does:

void TakesBool(bool b) {}

int main() {
//Base base; TakesBool(base); // compilation error (as expected)
Derived derived; TakesBool(derived);
return 0;
}


This seems to indicate that
Derived
has an (non-
explicit
)
operator bool
, which, however, is marked
override
without a
virtual
declaration. How is this possible?

Answer

You might think the non-explicit operator bool in Derived doesn't override explicit operator bool in Base, but it does. The explicit specifier doesn't matter here.

From the standard, $10.3/2 Virtual functions [class.virtual]:

(emphasis mine)

If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

So the compiler will complain this only when the name, parameter-type-list, cv-qualification or ref-qualifier of the function doesn't match, explicit specifier will not be considered. It's not a part of the signature of the function.

Comments