我可以投射一个POD阵列,浮动浮动*?

Sam*_*rsa 7 c++ arrays containers

考虑以下:

#include <vector>
using namespace std;

struct Vec2
{
  float m_x;
  float m_y;
};

vector<Vec2> myArray;

int main()
{
  myArray.resize(100);

  for (int i = 0; i < 100; ++i)
  {
    myArray[i].m_x = (float)(i);
    myArray[i].m_y = (float)(i);
  }

  float* raw;
  raw = reinterpret_cast<float*>(&(myArray[0]));
}
Run Code Online (Sandbox Code Playgroud)

raw保证有正确的值200辆连续花车?也就是说,标准是否保证这一点?

编辑:如果以上是有保证的,如果Vec2有一些功能(非虚拟)和构造函数,是否仍然有保证?

注意:我意识到这很危险,在我的特殊情况下,我没有选择,因为我正在使用第三方库.

Evg*_*yuk 5

我意识到这很危险,在我的特殊情况下,我没有选择,因为我正在使用第三方库.

您可以添加结构大小的编译时检查:

现场演示

struct Vec2
{
    float a;
    float b;
};

int main()
{
        int assert_s[ sizeof(Vec2) == 2*sizeof(float) ? 1 : -1 ];
}
Run Code Online (Sandbox Code Playgroud)

这会增加你对你的方法的信心(由于reinterpret_cast,这仍然是不安全的,如上所述).


raw = reinterpret_cast(&(myArray [0]));

ISO C++ 98 9.2/17:

指向POD结构对象的指针(适当地使用reinterpret_cast转换)指向其初始成员(或者如果该成员是位字段,则指向它所驻留的单元),反之亦然.[注意:因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐. - 尾注]


最后,相应地址的运行时检查会使这种解决方案相当安全.它可以在单元测试期间甚至在程序的每个开始时(在小型测试阵列上)完成.

把它们放在一起:

现场演示

#include <vector>
#include <cassert>
using namespace std;
struct Vec2
{
    float a;
    float b;
};

int main()
{
    int assert_s[ sizeof(Vec2) == 2*sizeof(float) ? 1 : -1 ];
    typedef vector<Vec2> Vector;
    Vector v(32);
    float *first=static_cast<float*>(static_cast<void*>(&v[0]));
    for(Vector::size_type i,size=v.size();i!=size;++i)
    {
        assert((first+i*2) == (&(v[i].a)));
        assert((first+i*2+1) == (&(v[i].b)));
    }
    assert(false != false);
}
Run Code Online (Sandbox Code Playgroud)

  • 问题是标记为C++,因此您可以使用C++ 11,因为C++在询问时就是C++ 11.如果你想要C++ 03,请将问题标记为C++ 03. (2认同)