Edit to include AnT comments:
Clang behaves correctly following the C ++ name hiding rule. A brief description is available here . In short ...
A member of a derived class hides any member of the base class that has the same name as the member of the derived class.
This includes the base class methods marked virtual .
Original answer:
It seems that Klang gives priority to the name of the function, rather than the signature when choosing the method you are trying to call. Here is an example of using your classes ...
int main(void) { Final f; f.foo(3.14159); f.foo(0); Middle* m = static_cast<Middle*>(&f); m->foo(3.14159); m->foo(0); Base* b = static_cast<Base*>(&f); b->foo(3.14159); b->foo(0); }
Note the additional warning generated on the call site ...
32 : <source>:32:12: warning: implicit conversion from 'double' to 'int' changes value from 3.14159 to 3 [-Wliteral-conversion] m->foo(3.14159); ~~~ ^~~~~~~
https://godbolt.org/g/qkjqEN
Even if the Middle class inherits the void foo(double) method from Base , Clang seems to assume that you intended to call the void foo(int) override method declared in Middle .
As already mentioned, you can add more overrides to help Clang resolve the method you intended to call. Another solution is provided by fooobar.com/questions/122130 / ... with the using keyword. Announcements in Middle and Final will become the following ...
struct Middle : public Decorator<Base> { using Base::foo; void foo(int) override { std::cout << "Middle::foo" << std::endl; }; }; struct Final : public Middle { using Base::foo; void foo(double) override { std::cout << "Final::foo" << std::endl; }; };
https://godbolt.org/g/Qe1WMm
v1bri source share