我想写一个任意维度的 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;
}
我相信它是安全的,因为:
- 如果 T 是 POD,则 _vectorNd 类型是 POD(简单地可复制且 标准布局)
- 既然是POD,就必须兼容C,而C需要存储 字段按照声明的顺序排列,因此不允许重新排序。
还有其他问题会导致不安全吗?
最佳答案
严格来说,C++中的指针运算是基于数组定义的。也就是说,如果它不是一个对象数组,那么您只能前进一个元素(为了允许将单个对象视为一个元素的数组,您需要一个“越过末尾”指针)。您不能将包含两个T
对象的struct
视为一个包含两个数组的结构T
对象。
C++ 不允许将算术指针从一个子对象指向另一个子对象,除非这两个子对象都是同一数组的直接成员。
现在是的,几乎在您使用的每个编译器中,这都可以工作。但就标准而言,无论类型是否为“POD”,这都是未定义的行为。
关于c++ - 假设 C++11 中已知子级布局,重新解释基类是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49720653/