在C ++中获取相反的结构字段

Get opposite structure field in C++

让我们假设我有以下结构:

struct Point
{double _x, _y;};
struct Segment
{Point _p1, _p2;};
typedef Point Segment::* const SegmentEnd;

现在我想介绍一下根据所提供的 SegmentEnd 缩放分段的功能。这意味着更改与提供的 SegmentEnd 相反的坐标。我该怎么做?

这是我更改提供的 SegmentEnd 的代码,但我需要更改相反的代码:

void scale(Segment& segment, SegmentEnd end, const double& scaleVal)
{
    Point& p(segment.*end);
    p._x = scaleVal*p._x;
    p._y = scaleVal*p._y;
}

你可以定义一个函数,returns另一端:

SegmentEnd opposite(SegmentEnd e)
{
    return e == &Segment::_p1 ? &Segment::_p2 : &Segment::_p1;
}

// ...
Point& one(segment.*end);
Point& other(segment.*opposite(end));

如果您要求的是访问另一个成员(您没有提供作为参数的成员),您可能会比较您发送的元素的地址,比如 _p1,如果匹配你知道你想访问 _p2 而不是等。但是如果你想要最少的可读性,你应该以另一种方式真正解决你的问题。

我从未遇到过指向成员的访问运算符可以改进我的代码的情况,我相信阅读您的 post 此处不会改变。

编辑: 所以替代答案是在问题的评论中(Francois 的 ninjad),使用枚举或布尔参数来告诉在哪一端进行操作。

你不能简单地做类似的事情:

void scale(Segment& segment, bool inverted, const double& scaleVal)
{
    if (!inverted) {
        // scale segment._p1 with respect to segment._p2
    } else {
        // scale segment._p2 with respect to segment._p1
    }
}

那么你甚至不需要fiddle成员指针。

参数也可以是枚举 ("direction") 等等

您可能会争辩说,使用指向成员的指针您希望保存分支,但在您的情况下并非如此,因为您仍然需要检查地址以确定已发送哪个点。

您可以通过提供两个点(缩放的一个和另一个作为参考)来保存分支:

void scale(Segment& segment, SegmentEnd scaled, SegmentEnd reference, const double& scaleVal)
{
    // scale segment.*scaled with reflect to segment.*reference
}

并适当调用:

scale(segment, Segment::_p1, Segment::_p2, value);
scale(segment, Segment::_p2, Segment::_p1, value);

(或者直接传分)