Transition Prevention for C Style Array Pointers

struct Entry
{
    int Data0;
};

struct ExtendedEntry : public Entry
{
    int Data1;
};

I have a simple method waiting for a C-style array pointer for Entry like this

void Calculate(Entry* data, int count);

This method obviously fails when passing the pointer to the ExtendedEntrys array. How to prevent users from doing this?

ExtendedEntry items[50];
// [...]
Calculate(items, 50);

Not that I was chasing a bulletproof API, I just want to stop me and my colleagues from repeating the same error.

+6
source share
3 answers

Make a simple shell:

template <typename TEntry>
void CalculateSafe(TEntry* data, int count)
{
    static_assert(sizeof(TEntry) == sizeof(Entry), "size mismatch");
    Calculate(data, count);
}

This allows you to pass any derived type as long as it has the same size, which will solve the problem that you encountered when the C API must perform arithmetic of pointers in an array.

+7
source

@ John Zwinck's solution is very nice!

, . :

template < class T >
void Calculate(T * arr, int count)
{
    static_assert(std::is_base_of<Entry, T>::value, "true");

    for (int i = 0; i < count; i++)
        std::cout << arr[i].Data0 << std::endl;
}

, static_assert , .

+2

Or you can declare remote overload:

template<class T,std::size_t N>
std::enable_if_t<!std::is_same_v<T,Entry>> 
Calculate(const T(&)[N],int)
  = delete;

You can also replace type comparisons with type comparisons.

0
source

All Articles