[英]C++ overloading operator() in struct
這是來自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)
{
return (&x)[i];
}
...
float x, y;
}
為什么我們不能只使用SomeVector.x和SomeVector.y來讀/寫矢量坐標? 實際上如何換行return (&x)[i];
作品? 我的意思是,在結構的x組件引用之后的數組brakets []對我來說並不清楚。
在此先感謝您的回復。
這是來自Box2d物理引擎的b2Math.h的代碼。
您發布的Box2D源代碼的復制和粘貼似乎有錯誤。 特別是,在非const方法中似乎缺少了&符號。
此外,此代碼段似乎來自除當前2.3.2發布代碼之外的代碼庫。
以下是GitHub上Box2D 2.3.2源代碼的部分:
/// 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];
}
為什么我們不能只使用SomeVector.x和SomeVector.y來讀/寫矢量坐標?
我們可以,而且我們通常這樣做。
然而,Box2D中的一些代碼(具體為b2AABB::RayCast
)似乎是從算法編寫的( b2AABB::RayCast
的評論說“來自實時碰撞檢測,p179”)迭代x和y為數組下標零和一。 我猜想Erin Cato(Box2D的作者)以這種方式實現了這些運算符:(a)使風格上的訪問更符合算法,(b)使其工作,(c)使其工作在看似高效的方式。 我可以確認它至少起作用了。
我有自己的Box2D分支 ,我在其中重寫了這些運算符。 我將其接口更改為使用[]
(而不是()
),並將其實現更改為使用switch
語句顯式訪問x
或y
。 后者我明確地避免了使用C ++標准時可能未定義的行為。
這里是我的實現的相關部分的代碼段 (請注意,我並不認為這是完美或好的,只是它的替代實現有效並且應該明確依賴於定義的行為) :
/// 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;
}
實際上如何換行(&x)[i]; 作品?
正如我上面暗示的那樣,我之前已經研究過這個問題。
當結構的x和y成員變量的內存布局與具有兩個浮點數的數組相同時,它可以工作; 它通常做的。 因此&符號( &
)獲取x
參數的地址,然后將該地址視為數據開頭的地址,然后由i
索引。
我不認為這是定義的行為,但就C ++標准而言。 然而,根據我的口味,它沒有明確定義。
希望這能回答你的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.