0

考虑一个类:

template<typename Type>
class CVector2
{
public:
    union {
        struct { Type x; Type y; };
        Type v[2];
    };

       // A bunch of methods for vector manipulation follow
}

它可以这样使用:

CVector2<int> vec;
vec.x = 1;
vec.y = rand();
// ...
vec.v[rand() & 1] = vec.x;

问题是,这个联合不是标准的 C++,因为没有命名结构。我只能看到一种使其成为标准的方法 - 命名结构:

union {
        struct { Type x; Type y; } xy;
        Type v[2];
      };

然后我要么必须使任何矢量场访问时间更长:

CVector2<int> vec;
vec.xy.x = 1;
vec.xy.y = rand();
// ...
vec.v[rand() & 1] = vec.xy.x;

或者我必须声明方便的方法,这会有所帮助,但在复杂的用例中,由于额外的大括号,访问仍然会变得很麻烦:

class CVector2
{
public:
    union {
        struct { Type x; Type y; };
        Type v[2];
    };

    Type& x() {return xy.x;}
    const Type& x() const {return xy.x;}
    Type& y() {return xy.y;}
    const Type& y() const {return xy.y;}
}

使用示例:

void setGeometry (CVector2<int> p1, CVector2<int> p2)
{
   setGeometry(CRect(CPoint(p1.x(), p1.y()), CPoint(p2.x(), p2.y())));
}

有没有更好的方法可以使 CVector2 类与我缺少的 -pedantic-errors 一起编译?

4

1 回答 1

1

好吧,即使您没有明确说明,我假设您的联合的目的是将数组重新解释为一对单独的对象(反之亦然)。考虑到在这两种情况下它存储相同数量的相同类型的对象,我只是看不到这种联合可能有什么其他用途。您的代码示例中的以下行也支持此假设

vec.v[rand() & 1] = vec.xy.x;

如果这确实是预期的用途,则不可能使其“兼容”。在 C++中,无论您的结构是否命名,这种访问都会导致未定义的行为。

在 C++ 语言中,每个时刻只有一个联合成员是活动的——最后一个被写入的成员。您可以阅读该活动成员,但不允许您阅读工会的其他成员。在 C++ 语言中,联合不能用于“重新解释”内存,即使“重新解释”不会更改目标类型。

C 语言最终放宽了对这种联合使用的长期限制,但 C++ 从未这样做过。在 C++ 中,访问联合的“非活动”成员是非法的。

于 2013-11-06T18:00:49.737 回答