2017-04-04 64 views
10

最近在我的公司,我們遇到了一個錯誤,我無法理解爲什麼它實際上是一個錯誤。對我們來說,似乎這應該編譯得很好,並允許我們顯式實例化一個類型爲bar :: foo的模板。手動實例化模板時出錯

mainy.cxx

int foo(int); 
namespace bar { 
    template <typename T> T foo(T a, T){return a;} 
} 

namespace bar { 
    using ::foo; 
} 

template int bar::foo(int, int); 

int main(){ 
    return 0; 
} 

G ++錯誤

[[email protected]:~/test]1047 $ g++ mainy.cxx 
mainy.cxx:10: error: 'int bar::foo(int, int)' should have been declared inside 'bar' 
mainy.cxx:10: error: 'int bar::foo(int, int)' is not declared in '::' 

我們已經確認這是在GCC 4.8,4.4和3.7鏗鏘的錯誤但是它似乎與Visual工作Studio 2015.

當我們試圖實例化時遇到了這個問題卻都包含<cstdio>之前<algorithm><cstdio>中有

namespace std { 
    using ::remove; 
} 

上什麼怎麼回事任何想法?

+0

是否需要使用上面列出的編譯器版本?如果沒有,您可以在https://godbolt.org上評估上面列出的代碼,並使用不同的編譯器查看生成的代碼。 – AhiyaHiya

+0

您發佈的代碼與'cstdio'和'algorithm'中的'std :: remove'不完全相似。如果將'int foo(int)'添加到'bar'開始,[ideone.com](http://ideone.com/40xVXX)似乎沒有問題。 –

+3

問題依然存在:上述代碼是否合法?如果是這樣,那麼我們在gcc中發現了一個bug。如果不是,那麼這個標準有一個問題。 – jlehrer

回答

4

看起來像這與an ancient bug in gcc有關,在這裏你不能通過使用ns::func明確地實例化一個模板,唯一的方法就是使用namespace ns { ... func; }來完成。這只是最近才修復的,並且與newer gcc your code will compile

順便說一下,與您所說的相反,您的代碼爲compiles with clang 3.7

+0

你能告訴我專業化正在宣佈哪裏嗎?顯式實例是否被認爲是專門化的? – jlehrer

+0

@jlehrer是的,你是對的。 gcc中的這個錯誤雖然涉及到很多與ns :: func相關的問題 – Pavel