struct Entry
{
int Data0;
};
struct ExtendedEntry : public Entry
{
int Data1;
};
我有一个简单的方法,期望像这样的
的C样式数组指针void Calculate(Entry* data, int count);
当将指针传递给ExtendedEntrys数组时,此方法显然失败。如何防止用户这样做?
ExtendedEntry items[50];
// [...]
Calculate(items, 50);
这不是我追求防弹API,我只是想阻止我和我的同事再次犯同样的错误。
答案 0 :(得分:7)
制作一个简单的包装器:
template <typename TEntry>
void CalculateSafe(TEntry* data, int count)
{
static_assert(sizeof(TEntry) == sizeof(Entry), "size mismatch");
Calculate(data, count);
}
只要它具有相同的大小,就可以传递任何派生类型,这将解决当C API需要在数组中进行指针运算时所遇到的问题。
答案 1 :(得分:2)
@John Zwinck的解决方案非常好!
然而,还有一种方法。您可以像这样定义方法:
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 :(得分:0)
或者您可以声明已删除的重载:
template<class T,std::size_t N>
std::enable_if_t<!std::is_same_v<T,Entry>>
Calculate(const T(&)[N],int)
= delete;
您也可以通过类型大小比较替换类型比较。