2

Using the next definitions

class A {};
class B : public A {};

void f(A* a) {}

calling f(new B) is possible because B* is implicitly converted to A*, right?

However, when doing the same with class templates like std::vector this generates a compile error.

void f(std::vector<A*> v)
{}

int main()
{
    std::vector<B*> v;
    f(v); //error! "no suitable user-defined conversion..."

    return 0;
}

Why is that?

McLovin
  • 3,295
  • 7
  • 32
  • 67

3 Answers3

2

std::vector<B*> and std::vector<A*> are a completely different types, but B is derived from A. To copy data from std::vector<B*> to std::vector<A*> use std::copy and std::back_inserter:

#include <algorithm> // std::copy
#include <iterator>  // std::back_inserter

std::vector<B*> b;
std::vector<A*> a;
std::copy( b.begin(), b.end(), std::back_inserter( a ) );

... or initialize a with uniform initialization:

std::vector<B*> b;
std::vector<A*> a{ b.begin(), b.end() };
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
1

std::vector<B*> and std::vector<A*> are different at all, since their template arguments' type are different.

As a workaround, you can use another ctor of vector, i.e. template<class InputIt> std::vector::vector(InputIt first, InputIt last), such as:

f(std::vector<A*>(v.begin(), v.end()));

or just(need c++11)

f({v.begin(), v.end()});

LIVE

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
0

As pointed out in the comment, std::vector<A*> is a different type than std::vector<B*>. That doesn't prevent you from storing B* objects in the std::vector<A*> vector. As you surmised, base class pointers can point to derived objects, which is why you can store them in the base class vector.

You also should make v a reference in f's prototype.

Punchline: You don't really need std::vector<B*>.

scooter me fecit
  • 1,053
  • 5
  • 15