2016-05-12 42 views
6

的我一直在我公司看到這樣的代碼隨處可見:不必要使用未命名空間C++

namespace { 

const MAX_LIMIT = 50; 
const std::string TOKEN = "Token"; 

} 

我很困惑,爲什麼你在這裏需要一個匿名的命名空間。一方面,您需要本地翻譯單元MAX_LIMITTOKEN。但是由於const的原因,沒有匿名命名空間就已經實現了。 static const和簡單const都實現本地翻譯單元。

另一方面,如果文件中的某個地方有一個名稱相同的變量,則沒有命名衝突。

int foo() 
{ 
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used. 
} 

這將證明匿名命名空間。但是你多長時間需要一個函數中的變量名,這個變量名實際上是由在函數外部聲明的const變量佔用的?我的答案是從來沒有。所以在實踐中,對我來說,不需要命名空間。任何提示?

+3

我會說一致性:這個'const'規則只適用於整型。 – Quentin

+6

@Quentin Huh?名稱空間範圍內的'const'具有內部連接,除非標記爲'extern',對於所有類型 –

+0

@ M.M我的壞!我不知道我從哪裏回想起,但我也很確定。至少我並不孤單:D – Quentin

回答

3

在這種特殊情況下,名稱空間確實是多餘的,因爲默認情況下,const名稱空間作用域變量確實具有內部鏈接。

考慮稍後更改代碼的可能性。也許其中一個變量畢竟不應該是const。但是使其爲非常量也會更改默認鏈接。即使在這種變化之後,匿名命名空間也會保持內部聯繫。換句話說,匿名命名空間分離了對常量和鏈接的關注。這是否是件好事,取決於上下文。

請注意,同樣的事情可以通過使用static關鍵字來實現。由於這與匿名命名空間具有完全相同的效果,所以選擇主要是審美的,因此基於觀點。

使用匿名命名空間而不是static的參數可能是一致的。您不能用static定義與內部鏈接的類型。由於某些內部符號(類型)不能在匿名名稱空間之外定義,因此可以使用約定來定義匿名名稱空間中的所有內部符號。當然,這樣的慣例將會像慣例一樣是一種趣味問題。

你的第二個反駁論證似乎是在反對不存在的差異。匿名名稱空間對名稱隱藏在函數作用域內沒有任何影響。

+0

@LightnessRacesinOrbit我考慮是否有辦法增加第三級的opipsption,但我不能夠深入。 – user2079303

+0

你無法深入......在你的意見中 –

5

如您所解釋的,namespace是多餘的。您可以刪除namespace {並匹配}

一個區別是,您可以有不同的名稱::TOKENunnamed_namespace::TOKEN。但是這可能只會增加混淆,並且最好能夠得到編譯錯誤。

不確定您的文章的後半部分是什麼,局部變量TOKEN陰影均爲::TOKENunnamed_namespace::TOKEN。所以這種變化對這種情況沒有任何影響。

0

可以說它提高了清晰度。有一個匿名名稱空間說得更加清楚「這個代碼僅僅是這個編譯單元的實現細節,並不是作爲單元接口的一部分」。因爲無論如何你必須以這種方式爲本地類或結構使用匿名命名空間(沒有其他方式來本地化它們),所以以這種方式封裝所有本地構造是合理的。