【问题标题】:Assigning same memory to class member variables using unions使用联合将相同的内存分配给类成员变量
【发布时间】:2011-07-28 16:25:10
【问题描述】:

我正在尝试矢量化现有的 Vector 类

class Vector
{
 public:
   float X,Y,Z;
};

尝试向量化类成员而不影响其他类访问这些成员变量

class Vector
{
 public:
   union{
      float X,Y,Z;
      vector float vec4;
   };
};

但是由于没有找到成员名称 X,Y,Z 存在编译器错误。有没有其他获取变量的方法?

作为参考,vector float 类型来自IBM™ Cell Broadband Engine™ Software Development Kit V3.0 for Multicore Acceleration

【问题讨论】:

  • 这条线看起来很不对劲:vector float vec4;.
  • 啊,我明白了。对此感到抱歉。但也许你应该提到这一点。 :)
  • 在一个声明器中声明三个浮点数并不能神奇地使它们成为一个“实体”。这只是一个简写。您必须将它们包装在一些结构中。

标签: c++ vector simd vectorization altivec


【解决方案1】:
struct VectorData {
  float X, Y, Z;
};

union VectorUnion {
  VectorData VecData;
  vector float vec4;
};


class Vector {
public:
  Vector() : X(u.VecData.X), Y(u.VecData.Y), Z(u.VecData.Z) {}
  float & X;
  float & Y;
  float & Z;
private:
  VectorUnion u;
};

这是我相信您可以使用标准 C++ 获得的最接近的 - 这会使 Vector 更大,并且需要您自己实现赋值运算符。

【讨论】:

  • 我认为是 MSVC 将匿名工会的成员提升到父范围作为扩展?
  • @Erik: `vector float vec4;'不会真正编译!
  • @Als:请参阅 Rinesh 的评论 - 他正在使用一些 SIMD 扩展,它定义了 vector float 类型的 a.o
  • 有没有办法像以前一样访问变量 X、Y、Z 并让 vec4 指向同一个位置。
  • @Erik:用你所拥有的&(u.X) == &(u.Y) == &(u.Z)。你需要另一个结构级别。
【解决方案2】:

在标准 C++ 中使用联合无法做到这一点。你只能阅读你以前写过的东西。所以写XYZ,然后读vec4会产生未定义的行为。

我建议创建一个成员函数vector float toVector() const,它会在需要时创建向量。或者你可以考虑定义一个成员operator vector float() const

【讨论】:

  • 是的,它是 UB,但它几乎得到了普遍的安全支持,而且 UB 经常被忽略......而且那些通常(并且非常正确地)像瘟疫一样避免 UB 的人。随心所欲。
【解决方案3】:

您无法完全按照您的意愿行事(使用代码中的语法)。

一个正确的例子:

union{
    float coords[4];
    vector float vec4;
};

然后你可以逐个元素地挑选出来。

或者:

union{
    struct {
        float X, Y, Z;
    } v;
    vector float vec4;
};

但是你通过.v.X访问值

【讨论】:

    【解决方案4】:

    这应该可以解决问题。

    #include <iostream>
    
    using namespace std;
    
    class Point
    {
    public:
        Point() { X = 0.0f; Y = 0.0f; Z = 0.0f; };
        ~Point() {};
    
        union
        {
            struct{
                float X; float Y; float Z;
            };
            float index[3];
        };
    
        float operator[](int it)
        {
            return index[it];
        };
    };
    
    void main()
    {
        Point p;
    
        p.X = 1.0f;
        p.Y = 2.0f;
        p.Z = 3.0f;
    
        cout << p[0] << " " << p[1] << " " << p[2] << endl;
    
        p.index[0] = 4.0f;
        p.index[1] = 5.0f;
        p.index[2] = 6.0f;
    
        cout << p[0] << " " << p[1] << " " << p[2] << endl;
    
        cin.get();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-11
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      相关资源
      最近更新 更多