Struct 允许在D中进行[i]和.xyz操作的快速向量结构?

Struct 允许在D中进行[i]和.xyz操作的快速向量结构?,struct,operator-overloading,d,Struct,Operator Overloading,D,我想在d中创建一个向量结构,其工作原理如下: vec u, v; vec w = [2,6,8]; v.x = 9; // Sets x v[1] = w.y; // Sets y u = v; // Should copy data 稍后,我还想添加类似u=v*u等内容,但以上内容现在就可以了。 我已经走了这么远: struct vec3f { float[3] data; alias data this; @property { float

我想在d中创建一个向量结构,其工作原理如下:

vec u, v;
vec w = [2,6,8];
v.x = 9; // Sets x
v[1] = w.y; // Sets y
u = v; // Should copy data
稍后,我还想添加类似
u=v*u
等内容,但以上内容现在就可以了。
我已经走了这么远:

struct vec3f
{
    float[3] data;
    alias data this;
    @property
    {
        float x(float f) { return data[0] = f; }
        float y(float f) { return data[1] = f; }
        float z(float f) { return data[2] = f; }
        float x() { return data[0]; }
        float y() { return data[1]; }
        float z() { return data[2]; }
    }
    void opAssign(float[3] v)
    {
        data[0] = v[0];
        data[1] = v[1];
        data[2] = v[2];
    }
}
现在,这几乎使它像我想要的那样工作,但我觉得非常不确定这是否是“正确的”。opAssign()是否应该返回一些值


我还想知道这是否真的是最快的?我尝试添加
别名数据[0]x等,但这不起作用。有什么想法吗?或者这是“怎么做的”?也许编译器足够聪明,可以看出属性函数或多或少都是别名?

总的来说,这看起来相当合理。出于赋值链接的目的,opAssign应该返回v。然而,在实践中,这经常被忽略,可能会导致性能下降(我不知道)。与D1不同,您可以从D2中的函数返回静态数组

就性能而言,考虑这一点的最佳方式是在组装级别。假设启用了内联,
x()
几乎肯定会内联。静态数组直接存储在结构中,无需额外的间接层。指令
返回数据[0]
将导致编译器生成从结构开头的偏移量读取的代码。这个偏移量在编译时是已知的。因此,调用
x()
很可能会生成完全相同的汇编指令,就好像
x
实际上是一个公共成员变量一样

不过,另一种可能性是使用匿名联合和结构:

struct vec3f
{
    union {
        float[3] vec;

        struct {
            float x;
            float y;
            float z;
        }
    }

    alias vec this;  // For assignment of a float[3].

}

请注意,尽管
别名this
目前存在相当多的错误,除非您愿意提交一些错误报告,否则您可能还不应该使用它。

您可以使用它进行任意深度的旋转。我还建议根据大小和类型模板化向量结构。以下是我的比较版本:(D1,所以swizzling有点麻烦)。

您可以使用数组操作在opAssign中一次性复制整个数组:

data[] = v[];
为什么是房地产

我建议删除这些行,并将x、y和z字段设置为公共字段。
这也将提高非内联模式下的性能。无论如何,您都可以使用union来创建数据[3]数组。

+1,我对使用opDispatch进行Swizzing也有相同的想法。我仍然处于D的早期阶段,所以我的解决方案可能没有它可能的那么好。不过,你可以做的编译时工作令人难以置信!
@property
    {
        float x(float f) { return data[0] = f; }
        float y(float f) { return data[1] = f; }
        float z(float f) { return data[2] = f; }
        float x() { return data[0]; }
        float y() { return data[1]; }
        float z() { return data[2]; }
    }