2010-04-08 70 views
2

誰能解釋一下下面的代碼行,在http://docs.openttd.org/ai__cargo_8cpp_source.html強制轉換和命名空間運算符之間沒有空格?

return (AICargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect; 

發現如果這條線是:

return (AICargo::TownEffect) ::CargoSpec::Get(cargo_type)->town_effect; 

(注意TownEffect)::之間的空間),那麼我會明白罰款。但是該文檔中沒有空格*,這意味着(AICargo::TownEffect)是::運算符的左操作數。

這段代碼是如何工作/編譯的?還是由於一些模糊的C++規則,這兩件事情是等價的?

*在cpp文件中也是如此。

回答

8

除了分離令牌之外,空白在C++語法中一般不重要。

小括號顯著,他們不能出現在合格-ID所以之間沒有等價:

(AICargo::TownEffect)::CargoSpec::Get 

AICargo::TownEffect::CargoSpec::Get 

在第一個有兩個合格ID,一個用括號命名一個類型,另一個命名一個函數。在這種情況下,括號內類型的唯一有效解釋是演員表演。右括號後面是否有空格不區分。

+1

從技術上講,'AICargo :: TownEffect'是一個_type-id_而不是_qualified-id_,因爲它命名了一個類型而不是一個對象或函數。 – 2010-04-08 12:51:39

1

這是一個簡單的解析問題:這裏沒有必要使用空格,因爲我們知道C風格的轉換以括號結束。

它沒有更多的不可讀的是:

if(cargo_type){return cargo_type->town_effect;} 

它可能是從一個事實,即()不能作爲標識符的一部分莖。

1

查爾斯是正確的,他說在合格代碼中不能有括號。

我想補充一點,在C++中,您不應該使用舊的C風格轉換作爲風格問題。他們通常比你想要的更強,並丟棄const,這通常不是你想要的。此外,他們實際上無法搜索您的代碼庫,因此很難查看通常更容易導致錯誤的表達式。在這種情況下,如果您確實需要C風格演員的全部力量(此時不考慮const),則應使用reinterpret_cast<AICargo::TownEffect>。但是,如果沒有查看代碼,只要static_cast就足夠了,就不會感到意外。

+0

雖然應該指出,'static_cast'不會提高安全性,可能在調試模式下應該替換'dynamic_cast'。 – 2010-04-08 12:59:54

+0

相反:引用Stroustrup時,「* static_cast *運算符在相關類型之間轉換,例如在同一個類層次結構中將一個指針類型轉換爲另一個類型,將枚舉轉換爲整數類型或將浮點類型轉換爲整型。 * reinterpret_cast *處理不相關類型之間的轉換,例如指向一個指針的整數或指向不相關指針類型的指針。這種區別允許編譯器對* static_cast *應用一些最小類型檢查,並且使程序員更容易找到更危險的轉換表示爲* reinterpret_cast * s。「 – jemfinch 2010-04-08 13:06:21

+5

@Matthieu M .:'dynamic_cast'和'static_cast'做了完全不同的事情。交替使用它們(例如,在不同的構建配置中)正在尋求麻煩。如果發佈版本正確使用'static_cast',那麼調試版本也應該如此。唯一一次你可能想要在調試版本中使用'dynamic_cast'而不是在發佈版本中會使用'assert'。 – 2010-04-08 13:09:35