假设 C++11 中已知子级布局,重新插入基类是否安全

Is it safe to reinterpet a base class assuming layout of child is known in C++11?

本文关键字:新插入 插入 安全 是否 基类 C++11 布局 假设      更新时间:2023-10-16

我想写一个任意维度的向量类型。 问题是我想为某些维度(例如:x,y,z(使用单独的字段,我的解决方案是使用 CRTP 混合我需要的功能:

#include <unistd.h>
template <typename B, typename T, int DIM>
struct _veccore {
    // convert vector to array of underlying scalar type
    T* data(ssize_t ii) { return (static_cast<T*>(this))[ii]; }
    B operator +(const B& ov) {
        B b = reinterpret_cast<B*>(*this);
        for (ssize_t ii=0; ii < DIM; ii++) {
            b.data(ii) += ov.data(ii);
        }
        return *this;
    }   
};

template <typename T> struct _vector1d : _veccore<_vector1d<T>, T, 1> { T x;     };
template <typename T> struct _vector2d : _veccore<_vector2d<T>, T, 2> { T x,y;   };
template <typename T> struct _vector3d : _veccore<_vector3d<T>, T, 3> { T x,y,z; };
int main() {
    _vector1d<float> v1f;
    _vector2d<float> v2f;
    _vector3d<float> v3f;
}

我相信它是安全的,基于:

  1. 如果 T 是 POD,则_vectorNd类型为 POD(三元可复制和标准布局(
  2. 因为它是 POD,它必须是 C 兼容的,而 C 需要存储字段按声明顺序排列,因此不允许重新排序。

还有其他陷阱会使这不安全吗?

严格来说,C++中的指针算术是基于数组定义的。也就是说,如果它不是一个对象数组,那么你只能前进一个元素(为了允许将单个对象视为一个元素的数组,你需要一个"结束"指针(。不能将包含两个T对象的struct视为包含两个T对象的数组的结构。

C++ 不允许将算术从一个子弹出指针到另一个子弹射,除非这两个子对象都是同一数组的直接成员。

现在,是的,在

您使用的几乎每个编译器中,这都可以工作。但就标准而言,无论类型是否为"POD",它都是未定义的行为。