2010-02-12 79 views
0

我遇到了一個編譯..奇怪?最近這讓我相信創建模板時會創建與聲明位置相同的命名空間(或至少相同的命名空間)。那是;模板/命名空間互動

template<class T> 
class bar 
{ 
public: 
    static int stuff(){return T::stuff();} 
}; 

namespace ONE 
{ 
    struct foo 
    { 
     static int stuff(){return 1;} 
    }; 
} 

namespace TWO 
{ 
    struct foo 
    { 
     static int stuff(){return 2;} 
    }; 
} 


using namespace TWO; 

int main() 
{ 

    return bar<foo>::stuff(); 
} 

將返回1時using namespace ONE和2時using namespace TWO

爲什麼?命名空間和模板之間還有其他「奇怪」或「意外」的相互作用嗎?

編輯:這當時令人困惑,因爲在多個文件中使用相同的模板,每個文件都使用不同的名稱空間。

+6

這並不是所有的「奇怪」。 '使用namespace ONE'將等同於'bar :: stuff()',並按預期工作。 – 2010-02-12 02:03:41

+0

我一定錯過了什麼?這對我來說似乎是正確的?酒吧是酒吧或酒吧是不是。所以這些數字似乎正確? – 2010-02-12 02:05:41

回答

6

這並非意外。您沒有資格獲得您想要的foo,所以您的using聲明告訴編譯器在哪裏找到它。

我在生產代碼中看到的最糟糕的模板gotcha必須處理非依賴名稱查找。這很複雜,所以最好指出C++ FAQ Lite(第35.18-20節)。

5

我不確定這裏有什麼令人驚訝的。當您說using namespace ONE時,您將ONE :: foo帶入範圍,現在確認爲foo。在上面的代碼中,模板獲取TWO :: foo作爲其參數。它與模板無關,當你調用bar<T>::stuff()時,main()中發生的所有事情都會發生。