这是一个具有所需语法的解决方案,并且不会增加类的大小。它在技术上是正确的,但相当复杂:
union Vector3 {
struct {
float x, y, z;
auto& operator=(float f) { x = f; return *this; }
operator float&() & { return x; }
operator const float&() const & { return x; }
operator float () && { return x; }
float* operator&() { return &x; }
} x;
struct {
float x, y, z;
auto& operator=(float f) { y = f; return *this; }
operator float&() & { return y; }
operator const float&() const & { return y; }
operator float () && { return y; }
float* operator&() { return &y; }
} y;
struct {
float x, y, z;
auto& operator=(float f) { z = f; return *this; }
operator float&() & { return z; }
operator const float&() const & { return z; }
operator float () && { return z; }
float* operator&() { return &z; }
} z;
struct {
float x, y, z;
auto& operator=(float f) { x = y = f; return *this; }
} xy;
struct {
float x, y, z;
auto& operator=(float f) { y = z = f; return *this; }
} yz;
struct {
float x, y, z;
auto& operator=(float f) { z = x = f; return *this; }
} zx;
};
另一个依赖的是owner_of
在这里实现:https://gist.github.com/xymopen/352cbb55ddc2a767ed7c5999cfed4d31这可能取决于一些技术上特定于实现的(可能是未定义的)行为:
struct Vector3 {
float x;
float y;
float z;
[[no_unique_address]]
struct {
auto& operator=(float f) {
Vector3* v = owner_of(this, &Vector3::xy);
v->x = v->y = f;
return *this;
}
} xy;
[[no_unique_address]]
struct {
auto& operator=(float f) {
Vector3* v = owner_of(this, &Vector3::yz);
v->y = v->z = f;
return *this;
}
} yz;
[[no_unique_address]]
struct {
auto& operator=(float f) {
Vector3* v = owner_of(this, &Vector3::zx);
v->z = v->x = f;
return *this;
}
} zx;
[[no_unique_address]]
struct {
auto& operator=(float f) {
Vector3* v = owner_of(this, &Vector3::zx);
v->x = v->y = v->z = f;
return *this;
}
} xyz;
};