Passing an array of pointers to child objects to a function that takes an array of pointers to parent objects

I want to do what’s said in the title but I run in the following error:

error: invalid conversion from ‘Child**’ to ‘Parent**’ [-fpermissive]

For clarity, here is my parent.hpp file:

#ifndef PARENT
#define PARENT

class Parent
{
    //something
};

#endif

Here my child.hpp file

#ifndef CHILD
#define CHILD
#include "parent.hpp"

class Child : public Parent
{
    //something
};

#endif

And here is the function I’m trying to use:

void func(Parent *p[])
{
    //something
}

int main()
{
    Child *c[10];
    func(c);
}

I would like to know why this happens while it does not when the parameter is a simple pointer, and how I could get it to work without using templates, provided such a way of solving the problem exists.

Answer

Passing an array of pointers to child objects to a function that takes an array of pointers to parent objects

You then need to create an array of Parent* that you populate with Child*s.

Example:

class Parent {
public:
    virtual ~Parent() = default;
};

class Child : public Parent {};

void func(Parent *p[]) {
    //something
}

int main() {
    Parent *c[10] {
        new Child, new Child, new Child,
        new Child, new Child, new Child,
        new Child, new Child, new Child,
        new Child,
    };
    
    func(c);
    
    for(auto p : c) delete p;
}

A better option is probably to use a vector (or std::array) containing unique_ptr<Parent> to not have to delete the objects when you are done with them.

#include <iostream>
#include <memory>
#include <vector>

class Parent {
public:
    virtual ~Parent() = default;

    virtual void foo() const { std::cout << "Parentn"; }
};

class Child : public Parent {
public:
    void foo() const override { std::cout << "Childn"; }
};

void func(std::vector<std::unique_ptr<Parent>>& p) {
    for(auto& ptr : p) ptr->foo();                   // prints Child 10 times
}

int main() {
    std::vector<std::unique_ptr<Parent>> c(10);

    for(auto& ptr : c) ptr = std::make_unique<Child>();
    
    func(c);
}