在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);
(或者直接传分)
让我们假设我有以下结构:
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);
(或者直接传分)