phimuemue phimuemue - 1 year ago 102
C++ Question

Virtual explicit conversion operator overriding

I have a class

defining an
explicit operator bool

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

And I have a subclass
, defining an
operator bool

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

As you can observe,
Derived::operator bool
is explicitly not marked
, but marked
, 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,
does not compile (as expected), but

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
has an (non-
operator bool
, which, however, is marked
without a
declaration. How is this possible?

Answer Source

You might think that the non-explicit operator bool in Derived doesn't override explicit operator bool in Base, no, it does. The explicit specifier doesn't matter, it's not a part of function signature.

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 only when the name, parameter-type-list, cv-qualification or ref-qualifier of the function doesn't match, the explicit specifier won't be considered.

You said "marked override without a virtual declaration", note that the virtual declaration for member function in derived class doesn't matter, it'll be also virtual.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download