I have the following code:
struct Abs {
virtual void f(int x) = 0;
virtual void f(double x) final { std::cout << 2; }
};
struct Sub: public Abs {
void f(int x) final { std::cout << 1; }
};
Abs
is an abstract class which comprises a pure member function void f(int)
and its overloaded version void f(double x)
, which is no longer pure and final
. If I try to override void f(int)
in the derived struct Sub
, it shadows void f(double)
and the following main
function prints 1
, converting 1.01
to int
:
int main() {
Sub x = {};
x.f(1.01);
return 0;
}
How do I overcome this problem? Also, why does it work like that?
CodePudding user response:
Given x.f(1.01);
, the name f
is found in the scope of class Sub
, then name lookup stops; the scope of Abs
won't be examined. Only Sub::f
would be put in overload set and then overload resolution is performed.
... name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.
You can use using
to introduce the names of Abs
into Sub
, then Abs::f
could be found and take part in overload resolution too.
struct Sub: public Abs {
using Abs::f;
void f(int x) final { std::cout << 1; }
};
CodePudding user response:
You have to add the using
clause into your derived class to pick all the overloads from the base class.
struct Abs {
virtual void f(int x) = 0;
virtual void f(double x) final {std::cout << 2;}
};
struct Sub: public Abs {
using Abs::f; // << this one did the trick
void f(int x) final { std::cout << 1; }
};
int main() {
Sub x = {};
x.f(1.01);
return 0;
}