2011-06-29 82 views
2

這真的很平凡,但我得到了一個我沒有想到的錯誤。引用全局名稱空間中的某些東西?

我有一些代碼,是一個命名空間

內的下面是一些僞代碼,代表我的代碼的結構:

namespace A { 
    void init() { 
     initialize_kitchen_sink(); 
    } 
    #include "operations.h" // declares shake_and_bake() 
    void foo() {    
     shake_and_bake(); 
    } 
    void cleanup() { 
     // do nothin' cuz i'm a slob 
    } 
} 

錯誤:

undefined reference to `A::shake_and_bake` 
+2

operations.h文件中的所有內容都在名稱空間A中聲明。如果將文件operations.h包含在另一個文件中但在不同的名稱空間(如全局)中,這些將完全不同。注意#include是預處理器的一部分,並且在任何語言構造完成之前就已經運行了。 –

回答

6

原來移動命名空間外部的#include將修復它。

實際上,include將實際上聲明A名稱空間中operations.h的所有函數。然後它會徒勞地搜索實現。

我認爲,不要刪除我的整個帖子,我可能會把它留給那些可能性,因爲別人可能會偶然發現類似的問題並開悟。

+0

更好的是,儘量把你的包含在源文件的頂部,而不是在你首先需要邏輯的中間 –

+0

我還沒有看到任何正確的理由不把頂部包含。我仍然有時會搞砸了,但例如,如果我將單元測試放在底部,'#include「unittest ++。h」'可能會在所有單元測試宏之前接近文件末尾。所以這似乎工作正常,但可能也是不好的形式。可能 –

3

要準確地回答你的問題,你可以通過使用::作爲您的第一條語句,如參考從全局命名空間的東西:

void foo() {    
     ::shake_and_bake(); 
    } 

當然,你的回答,對於這種特殊情況下是正確的,雖然。

+0

我不知道你可以做到這一點。在全局命名空間和當前命名空間中都聲明同名的東西的唯一情況是哪種情況會有用? –

+0

這也是我的理解。然而,我知道像gtest這樣的framworks(谷歌單元測試框架)比較依賴它,所以一定有一些你沒有其他選擇的情況! Koenig查找有時可能會變得複雜:) – Dinaiz

+0

從幾年前看我自己的問題的答案,並仍然學習的東西是很好的。 Koenig Lookup很酷,我一直在使用它。 –

相關問題