Why does the following snippet not compile?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct A
{
	virtual void method(int) {};
	int method() { return 0; };
};

struct A_child : public A
{
	virtual void method(int) override {}
};

int main()
{
    A* base = new A();
    A_child* child = new A_child();
    
    base->method();  //<-- That one works
    child->method(); //<-- Here the compiler expectes a parameter
    
    return 0;
}


Only when renaming the int method(); to something else, it works.
Last edited on
Because child is a A_child* it will first look for a function with a matching name in the A_child class before looking in base class A.

In this case it finds a function named "method" in A_child so it stops the search, without looking in A, but then it gives you an error because the function it found does not allow it to be called without passing arguments.

To work around this issue you can add using A::method; to the A_child class.

1
2
3
4
5
struct A_child : public A
{
	using A::method;
	virtual void method(int) override {}
};

But a better solution is probably to use different function names.
Last edited on
You can't have two members with the same identifier and hence when you rename it, it works (haven't read about derived classes yet so don't know what you were trying to do with virtual).
Last edited on
The issue isn't just that they are the same identifier, that's call overload resolution.
method() and method(int) could both be defined/used together if they were in the same scope.
The issue is specifically that there isn't overload resolution between the base class and derived class (i.e. between different scopes).

BTW, here's a stroustrup link to what Peter87 was talking about:
http://www.stroustrup.com/bs_faq2.html#overloadderived

But a better solution is probably to use different function names.
This. Avoid the confusion.
Last edited on
Topic archived. No new replies allowed.