通过指针访问非数组浮点数
Accessing non-array floats via pointers
这是有效/可移植/合法的代码吗?
class Vector3
{
public:
float& operator [] ( const size_t i )
{
assert( i < 3 );
return *(&x+i);
}
float x, y, z;
};
有相当多的实例,我想使用[]
操作符,最终把元素放在一个数组中(以避免if/switch语句)。我从来没有用这种方法做过。我可以告诉为什么它工作(x,y和z是连续的),但它是好的(或至少是ok的)实践?
另外,代码是否要求#pragma pack 1
保证无垫包装,或者没有它可以工作?我问的原因是,因为片段实际上是从Ogre3D矢量类,我没有看到#pragma pack 1
在任何地方。
No。这是不正确的,也不是好的做法。很可能在三个元素之间没有填充(即使没有指示编译器打包结构),因此您很可能能够像访问数组元素一样访问成员。但是,这并不能使代码正确:所写的代码会产生未定义的行为。
正确的方法是为组件使用访问器函数,例如
struct Vector
{
float& operator[](std::size_t i) { return data_[i]; }
float operator[](std::size_t i) const { return data_[i]; }
float& x() { return data_[0]; }
float& y() { return data_[1]; }
float& z() { return data_[2]; }
float x() const { return data_[0]; }
float y() const { return data_[1]; }
float z() const { return data_[2]; }
private:
float data_[3];
};
我相信它确实有效,因为c++编译器不允许在单个访问说明符内重新排序类/结构的成员-所以它们总是必须排列为x, y, z。这是为了向后兼容C,在C中编译器根本不允许重新排序成员。
然而,我认为这对它自己来说有点太聪明了。对我来说,在操作符内部设置几个if或开关似乎更干净,尽管我猜他们可能认为如果它是一个Ogre向量,那么它可能是性能关键的,所以这可能是这样做的原因。
我不认为包装pragma是必要的,因为所有三个成员都是相同的大小,所以你会期望他们彼此有关。但我并不是百分百肯定。
如果代码假设32位浮点是连续的,那么64位机器将结构元素对齐到64位边界将失败,很可能没有警告。
仅仅因为它在我所知道的所有32位和16位架构中的所有实现上都有效,并不意味着它通常有用。最好的情况下,它是一个特殊的情况下,工作在多个实现。据推测,未来将出现128位和256位架构,在这些架构中,它可能会像奇怪的那样失败。
这些隐藏的假设给那些继承了这些代码的人带来不必要的痛苦和折磨——如果你忘记了它,甚至可能是你。它的表达方式如此可疑,以至于很难理解任何微薄的利益都被证明是为了什么利益而进行的交易。请学习KISS原则。知道。住它。喜欢它。
- 将浮点数转换为无符号字符数组并打印出来
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- C++浮点数和字节数组的联合问题
- C/C++ - 将浮点数转换为字节数组,以便字节保持排序
- 如何创建带有字符串和浮点数的 2D 数组
- 如何使用 c++ 模板实现整数、字符串、浮点数和日期对象的数组
- 如何创建用于存储和返回浮点数数组的结构
- 我可以在CUDA设备上为包含浮点数数组的对象分配内存吗
- 使用memcpy将浮点数组复制到uint8_t的数组是否有效
- 如何将 4 个浮点数的 ps 向量转换为 4 个双精度并存储到 pd 数组
- 如何将.txt文件中的浮点数据写入带有VS2017的二维数组
- 在同一行中读取混合输入(字符串/浮点数),并将其存储在数组中
- 如何将数组的一部分从 int 转换为浮点数并将值设置为另外两个数组
- 如何将变量从主机上的自定义类数组复制到 CUDA 中设备上的浮点数组中
- std::copy 将双精度数组复制到浮点数数组
- 将“复制浮点数组”设置为“多维数组”
- 将正浮点数组转换为无符号短数组,并按C++舍入
- C++ 程序,用于将具有恒定(但未知)列数的未知大小的 CSV 文件(仅填充浮点数)读取到数组中
- 如何使用zmq/zeromq从传递给python的字符串表示(字节数组)中获取整数/浮点数
- 通过指针访问非数组浮点数