Reputation: 305
I want to define a function in a base class and a function with the same name and another signature in a subclass like this:
class A {
public:
void foo () {}
};
class B : public A {
public:
void foo(int x) {}
};
int main() {
B b;
b.foo();
}
But it causes compile error: no matching function for call to ‘B::foo()’
.
If I comment foo
definition in class B, it compiles.
How to solve the problem?
What I really want is to define a polymorhic interface in a base class and redefine semantic in child classes.
UPD: Thanks, the answers worked for this example. But it doesn't seem to work with templates: sort.h
...
class Sort {
public:
template <typename TArr>
static TArr& sort(TArr& array) { return sort(array, array.size()); }
};
class BubbleSort : public Sort { // add inheritance
public:
using Sort::sort;
template <typename TArr>
static TArr& sort(TArr& array, size_t len) {
...
}
};
test.cpp
...
int main () {
...
std::array<int, 5> test_array {3, 2, 5, 1, 4};
BubbleSort::sort(test_array)
...
}
When I run this, I get:
sort.h: In instantiation of ‘static TArr& Sort::sort(TArr&) [with TArr = std::array<int, 5ul>]’:
test.cpp:9:30: required from here
sort.h:17:47: error: no matching function for call to ‘Sort::sort(std::array<int, 5ul>&, std::array<int, 5ul>::size_type)’
static TArr& sort(TArr& array) { return sort(array, array.size()); }
^
sort.h:17:16: note: candidate: template<class TArr> static TArr& Sort::sort(TArr&)
static TArr& sort(TArr& array) { return sort(array, array.size()); }
^
sort.h:17:16: note: template argument deduction/substitution failed:
sort.h:17:47: note: candidate expects 1 argument, 2 provided
static TArr& sort(TArr& array) { return sort(array, array.size()); }
Why does it happen?
UPD: Got that.
Upvotes: 0
Views: 40
Reputation: 17483
Function f
from the derived class simply hides all the functions with the same name from the base class.
To solve it you can use a using-declaration:
class B : public A {
public:
using A::foo;
void foo(int x) {}
};
Upvotes: 1
Reputation: 32586
But it causes compile error:
no matching function for call to ‘B::foo()’
Try using-declaration
:
class A {
public:
void foo() {}
};
class B : public A {
public:
using A::foo;
void foo(int x) {}
};
What I really want is to define a polymorphic interface in a base class and redefine semantic in child classes.
Well, you should make the base class function virtual
an have the same parameters when override it. Otherwise, how the subclass function is supposed to be called via a reference/pointer to the base class?
Upvotes: 2
Reputation: 490623
Without virtual
, the A::foo()
doesn't define a polymorphic interface.
Anyway, you can make A::foo()
visible via B
with a using
declaration:
class B : public A {
public:
using A::foo;
void foo(int x) {}
};
This provides polymorphism to the extent that you accept function overloading as polymorphism--i.e., A::foo()
and B::foo()
form an overload set, and the compiler chooses which to call based on the parameter(s) you pass (if any), the same way as if B
contained two overloaded functions (with the same signatures as the existing A::foo
and B::foo
).
Upvotes: 2