diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 8df991e..f861b15 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -6561,11 +6561,49 @@ This a relatively rare use because implementation can often be organized into a ##### Reason -??? +Without a using declaration, member functions in the derived class hide the entire inherited overload sets. -##### Example +##### Example, bad - ??? + #include + class B { + public: + virtual int f(int i) { std::cout << "f(int): "; return i; } + virtual double f(double d) { std::cout << "f(double): "; return d; } + }; + class D: public B { + public: + int f(int i) override { std::cout << "f(int): "; return i+1; } + }; + int main() + { + D d; + std::cout << d.f(2) << '\n'; // prints "f(int): 3" + std::cout << d.f(2.3) << '\n'; // prints "f(int): 3" + } + +##### Example, good + + class D: public B { + public: + int f(int i) override { std::cout << "f(int): "; return i+1; } + using B::f; // exposes f(double) + }; + +##### Note + +This issue affects both virtual and non-virtual member functions + +For variadic bases, C++17 introduced a variadic form of the using-declaration, + + template + struct Overloader : Ts... { + using Ts::operator()...; // exposes operator() from every base + }; + +##### Enforcement + +Diagnose name hiding ### C.139: Use `final` sparingly