5

Starting from this question:

And considering this simplified code:

#include <string>
#include <iostream>

class Abstract
{
public:
    virtual void method(int a)
    {
        std::cout << __PRETTY_FUNCTION__ << "a: " << a << std::endl;
    }
};

class Concrete : public Abstract
{
public:
    void method(char c, std::string s)
    {
        std::cout << __PRETTY_FUNCTION__ << "c: " << c << "; s: " << s << std::endl;
    }
};

int main()
{
    Concrete c;
    c.method(42);    // error: no matching function for call to 'Concrete::method(int)'
    c.method('a', std::string("S1_1"));

    Abstract *ptr = &c;
    ptr->method(13);
    //ptr->method('b', std::string("string2"));    <- FAIL, this is not declared in Abstract.
}

I got two doubts. 1. I know I can solve the error if I "import" a method name from Abstract with

using Abstract::method;

but then I import all overloads of that name. Would it be possible to import only a given overload? (Suppose Abstract has more than one overload like:)

virtual void method(int a) = 0;
virtual void method(std::string s) = 0;
  1. Is it possible to import all (public|protected|all) names from Abstract at once without listing them one-by-one?

(Now suppose that in addition to method, Abstract also has:)

virtual void foo() = 0;
curiousguy
  • 8,038
  • 2
  • 40
  • 58
j4x
  • 3,595
  • 3
  • 33
  • 64
  • You can 'fix' your last commented line by doing: `dynamic_cast(ptr)->method('b', std::string{"ccc"});` Not sure if this is what you want though. – Hawky Jan 15 '20 at 19:52
  • Your linked code works. As it should, since this is public inheritance. You get a problem, when the inheritance is private. And then there is to my knowledge no way around that. – n314159 Jan 15 '20 at 19:58
  • I don't understand your second question. You only need to pull in the names of functions that you have explicitly hidden by naming something the same thing. – super Jan 15 '20 at 20:04
  • Yes, the demo works, @n314159. It will fail if the `using` is taken out. – j4x Jan 15 '20 at 20:16
  • OK, @super, but then I need to add all names one-by-one, and this gets too much boiler plate if base class is not so small as this minimal reproducible example. So the question is how to make all hidden names visible in a less verbose way? – j4x Jan 15 '20 at 20:18
  • 2
    Hiding names is not something you should be doing very often. If you do, I think it makes sense that you need to be explicit about the fact that you want to pull the hidden names into the current overload set. AFAIK there is no other way. – super Jan 15 '20 at 20:21
  • 2
    The short answer to your second question is "no". The hiding rule is *specifically designed* so each name in the derived class hides the same name in the base class, unless it is overridden *for that name* (e.g. `using Abstract::method`), with no way to turn it off. In fact draft C++ standards until about 1994, had no hiding rule, so what you want WAS the default. Using it was considered highly error-prone, so the hiding rule (in this specific context, at least) was *deliberately* introduced into the draft C++ standard in about 1995 to disallow it. – Peter Jan 16 '20 at 00:56
  • How was the question related to virtual inheritance? – curiousguy Jan 21 '20 at 20:16
  • 1
    If you want to make one specific overload from Abstract available just override it in the derived class: `void method(int a) { Abstract::method(a); }` Or did I misunderstand your question completely? – Jerry Jeremiah Jan 22 '20 at 00:38
  • 1
    This is useful information: https://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the/1629074#1629074 – Jerry Jeremiah Jan 22 '20 at 00:41
  • 1
    Another option is to just call the right function: `c.Abstract::method(42);` and `ptr->Abstract::method(13);` – Jerry Jeremiah Jan 22 '20 at 00:44
  • @j4x If a derived class hide so many methods, then something is wrong with your design. A class that has a lot of overload should probably be `sealed`. Adding more overload in derived classes is even more suspicious. And a class that has a lot of methods surely don't respect basic principles of good design like SRP (Single responsability principle).. – Phil1970 Jan 22 '20 at 01:13

0 Answers0