Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual explicit conversion operator overriding

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?

like image 405
phimuemue Avatar asked Aug 10 '16 13:08

phimuemue


People also ask

Under what circumstances should a conversion operator be explicit?

You can use a conversion operator when there is a natural and clear conversion to or from a different type. In general, any unit of measure is a good candidate for this.

What is conversion operator in c++?

Conversion Operators in C++ C++ supports object oriented design. So we can create classes of some real world objects as concrete types. Sometimes we need to convert some concrete type objects to some other type objects or some primitive datatypes. To make this conversion we can use conversion operator.


1 Answers

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 is superfluous, it's also virtual.

like image 77
songyuanyao Avatar answered Oct 06 '22 00:10

songyuanyao