假设 C++11 中已知子级布局,重新插入基类是否安全
Is it safe to reinterpet a base class assuming layout of child is known in C++11?
我想写一个任意维度的向量类型。 问题是我想为某些维度(例如: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",它都是未定义的行为。
相关文章:
- 在二叉搜索树中插入新元素
- 插入容器的容器(如果是新的或附加到现有容器)
- 插入新键时,它会更改现有键值的地址吗?
- 如果我们不创建一个新节点并使用指针插入数据并建立链接(在链表中)怎么办?
- 如何在使用 ItemType 的模板类时将新节点插入二叉树 c++.(我是 c++ 的新手)
- 在 std::unordered_map 中插入新的键/值对会导致"out of range"异常
- 有没有办法通过插入新类型名称而不是 int 来使用 2 位大小类型而不是 int?
- 通过字符串::插入插入字符时出错
- 在指向对象的指针的动态数组上插入新元素
- 在动态分配的二维矩阵中插入新列
- 新元素将在std :: set中插入哪里
- 在unordered_map/unordered_set中插入/放置新元素时的提示
- 插入新元素时结束迭代器会获得更新
- 将unordered_map的新实例插入到unordered_map中
- 新的STD :: MAP条目如何仅通过键插入初始化
- 在插入后与插入插入插件后对矢量进行排序
- C++链表——如何将每个新数据插入尾部
- 将新元素插入哈希表
- 在运行递归函数时将新元素插入向量时出现问题
- 为什么在尝试将新节点插入列表时出错