C++ C++;在结构中重载运算符()
下面是来自Box2d物理引擎的b2Math.h的代码C++ C++;在结构中重载运算符(),c++,struct,operator-overloading,box2d,C++,Struct,Operator Overloading,Box2d,下面是来自Box2d物理引擎的b2Math.h的代码 struct b2Vec2 { ... /// Read from and indexed element. float operator () (int i) const { return (&x)[i]; } /// Write to an indexed element. float operator () (int i) { ret
struct b2Vec2
{ ...
/// Read from and indexed element.
float operator () (int i) const
{
return (&x)[i];
}
/// Write to an indexed element.
float operator () (int i)
{
return (&x)[i];
}
...
float x, y;
}
为什么我们不能使用SomeVector.x和SomeVector.y来读取/写入向量坐标?以及如何实际行
返回(&x)[i]代码>有效吗?我的意思是,我不清楚引用结构的x组件之后的数组brakets[]
提前感谢您的回复
下面是来自Box2d物理引擎的b2Math.h的代码
您发布的Box2D源代码的复制和粘贴中似乎有错误。特别是,在非常量方法中似乎缺少一个符号
此外,此代码段似乎来自当前2.3.2版本代码以外的代码库
以下是来自以下内容的部分:
为什么我们不能使用SomeVector.x和SomeVector.y来读取/写入向量坐标
我们可以,而且通常都是这样
然而,Box2D中有一些代码(b2AABB::RayCast
特别是)似乎是由一个算法编写的(“code>b2AABB::RayCast
的注释说“来自实时碰撞检测,p179”),该算法以数组下标0和1的形式在x和y上迭代。我猜Erin Cato(Box2D的作者)是这样实现这些操作符的:(a)使访问在风格上更符合算法,(b)使其工作,以及(c)使其以一种看起来高效的方式工作。我可以确认它至少起作用了
我在其中重写了这些操作符。我将其接口更改为使用[]
(而不是()
),并将其实现更改为使用switch
语句显式访问x
或y
。后者我明确地避免了潜在的未定义行为W.R.T.C++标准。
下面是我的实现的相关部分的一个片段(请注意,我并不认为这是完美的,甚至不是好的,只是它是一个可行的替代实现,并且它应该明确地依赖于定义的行为):
///按索引访问元素。
///@param i索引(0表示x,1表示y)。
自动运算符[](大小\类型i)常量
{
断言(i
以及如何实际返回行(&x)[i];工作
正如我在上面暗示的,我以前已经研究过这个确切的问题
当结构的x和y成员变量的内存布局与具有两个浮点数的数组相同时,它就工作了;它通常是这样做的。因此,符号(&
)获取x
参数的地址,然后将该地址视为数组开头的地址,然后通过i
对其进行索引
我认为这不是定义的行为,但是就C++标准而言。然而,对我的口味来说,它的定义还不够清晰
希望这能回答您的问题。“为什么我们不能使用SomeVector.x和SomeVector.y来读取/写入向量坐标?”您如何声明
SomeVector
?这不在您的代码示例中。(&x)[i]
显示除0
之外的任何i
的未定义行为,因为它将尝试在未分配给此类数组的内存中执行数组索引。修改运算符()时出错
:应返回float&
。看起来您缺少完整回答问题的重要信息。然而,“为什么我们不能只使用SomeVector.x和SomeVector.y来读/写向量坐标?”很简单,你可以:)@CoryKramer我很确定在大多数实现中x
和y
在内存中是相邻的。这不能保证吗?(注意我不是OP。)
/// Read from and indexed element.
float32 operator () (int32 i) const
{
return (&x)[i];
}
/// Write to an indexed element.
float32& operator () (int32 i)
{
return (&x)[i];
}
/// Accesses element by index.
/// @param i Index (0 for x, 1 for y).
auto operator[] (size_type i) const
{
assert(i < max_size());
switch (i)
{
case 0: return x;
case 1: return y;
default: break;
}
return x;
}
/// Accesses element by index.
/// @param i Index (0 for x, 1 for y).
auto& operator[] (size_type i)
{
assert(i < max_size());
switch (i)
{
case 0: return x;
case 1: return y;
default: break;
}
return x;
}