c++ - 假设 C++11 中已知子级布局,重新解释基类是否安全?

标签 c++ c++11

我想写一个任意维度的 vector 类型。问题是我想为某些维度(例如: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”,这都是未定义的行为。

关于c++ - 假设 C++11 中已知子级布局,重新解释基类是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49720653/

相关文章:

c++ - 通过线程安全容器传递非线程安全对象

java - 如何按输入顺序输出C++11 unordered_map/unordered_set和Java HashMap/HashSet值?

c++ - Windows 多任务破坏了 OpenCL 性能

c++ - 在不取消停靠和停靠的情况下调整 QDockWidget 的大小

c++ - 在声明时对全局变量进行值初始化

c++ - 析构函数可以是最终的吗?

c++ - 在 C++11/C++14 中的类中存储对象类型的列表/映射

c++ - 当 C/C++ 中的数字常量以 0 为前缀时,这意味着什么?

c++ - 线程安全数据结构类的目的是什么?

c++ - C++11和C++14如何实现动态函数调用?