Riko Riko - 13 days ago 4
C++ Question

Implicit type cast in function pointers in C++?

I have 2 classes:

Child
derives from
Parent
:

#include <stdint.h>
#include <iostream>

using namespace std;

class Parent
{
public:
int parentMember;
};

class Child : public Parent
{
};


Now, I have a class template for custom implementation of a dynamic array (unnecessary parts skipped)

template <typename T>
class DArray
{
private:
T* m_array;
int32_t m_length;
public:

// Default constructor
DArray() : m_array{ nullptr }, m_length{ 0 } {
};

// Search returns index of the first found item or -1 if not found, comparison is done
// using function pointer, which should return boolean
int32_t Search(const T& data, bool(*comparisonFunction)(T, T)) {
for (int32_t i = 0; i < m_length; i++) {
if (comparisonFunction(m_array[i], data))
return i;
}
return -1;
}
};


I have a comparison function that will be used to find out if my dynamic array already contains an element with the same value of
parentMember


bool comparisonFunction(Parent* n1, Parent* n2) {
return (n1->parentMember == n2->parentMember);
}


Lastly, I have my dynamic array, which should hold pointers to
Child
objects.

int main()
{
DArray<Child*> dArray;
Child *c;
dArray.Search(c, comparisonFunction);
return 0;
}


This code returns error on this line:

dArray.Search(c, comparisonFunction);


The error is:

argument of type "bool (*)(Parent *n1, Parent *n2)" is incompatible with
parameter of type "bool (*)(Child *, Child *)"


My question is: Why doesn't the compiler implicitly convert
Child*
to
Parent*
as it does when I pass
Child*
as an argument to a function which takes
Parent*
as a parameter?

Is there any way how to solve this problem without implementing a new comparison function for every single child class?

Answer

The compiler won't do this.

Generally it is best to submit functors as template parameters that way it will work with any item that could compile in that place. std::function and capturing lambda's for example would work with template arguments but not explicit function pointer declaration.

template <typename T>
class DArray
{
private:
    T* m_array;
    int32_t m_length;
public:

    // Default constructor
    DArray() : m_array{ nullptr }, m_length{ 0 } {
    };

    // Search returns index of the first found item or -1 if not found, comparison is done 
    // using function pointer, which should return boolean
    template<typename COMPARE>
    int32_t Search(const T& data,COMPARE& compareFunction) {
        for (int32_t i = 0; i < m_length; i++) {
            if (comparisonFunction(m_array[i], data))
                return i;
        }
        return -1;
    }
};
Comments