Reputation: 4235
I have a class A
and its subclass B
and a method that takes std::vector<A>
. And I cannot make it work by passing std::vector<B>
.
I though that if subclass B
can be casted to A
, I should be able to pass vector of B
s to method that takes vector of A
s. How can I do that properly?
#include <iostream>
#include <vector>
class A {
public:
A() {}
};
class B: public A {
public:
B(): A() {}
};
void method(std::vector<A> a) {}
int main() {
std::vector<B> b;
method(b);
return 0;
}
When compiled:
g++ ex-cast-tag.cpp -std=c++11
ex-cast-tag.cpp:22:5: error: no matching function for call to 'method'
method(b);
^~~~~~
ex-cast-tag.cpp:18:6: note: candidate function not viable: no known conversion from 'vector<B>' to 'vector<A>'
for 1st argument
void method(std::vector<A> a) {}
^
1 error generated.
Thanks in advance!
Upvotes: 0
Views: 796
Reputation: 45414
One solution is to use a template. For example
template<typename C>
std::enable_if_t<std::is_base_of<A,C>::value>
method(std::vector<C> const&a)
{
// assume that a[i] is an A (derived or actually the same)
}
Here, I have used SFINAE to ensure that C
is actually A
or derived from A
. But you can also use static_assert
instead. In this case you get nicer error messages, but the overloading behaviour of method()
is different (i.e. when this template is considered).
Upvotes: 3
Reputation: 83517
If B
is a subclass of A
, it does not follow that std::vector<B>
is a subclass of std::vector<A>
. In order to use inheritance correctly here, you need to change the function to accept a parameter of type std::vector<A*>
then pass it a std::vector<A*>
whose pointers all point to instances of type B
. Alternatively, you can make the function into a template function.
Upvotes: 1