2016-04-15 36 views
4

的代碼錯誤路線參考如下:的Visual C++編譯器給出了模棱兩可的符號

namespace n1 
{ 
    template <class T> 
    void n2(); 

    template <class T> 
    void n2(T); 
} 

namespace n2 /* line 12 */ 
{ 
    class c {}; 
} 

using namespace n1; 

namespace n3 
{ 
    void foo(n2::c); 
} 

void n3::foo(n2::c) /* line 24 */ 
{ 

} 

當嘗試使用最新版本的Visual C編譯它++我得到以下錯誤:

1>test.cpp(24): error C2872: 'n2': ambiguous symbol 
1>test.cpp(12): note: could be 'n2' 
1>test.cpp(24): note: or  'n2' 

第12行和第24行在前面的代碼段中用註釋標記。

這是怎麼回事?如果我刪除了foo的定義並在函數參數列表外部聲明瞭一個類型爲n2 :: c的變量,那麼它編譯得很好,我想這是因爲編譯器認爲我引用的是類而不是任何模板函數。同樣,如果我刪除命名空間n1內的兩個n2模板函數的第二個定義,那麼編譯器會給我一個錯誤消息,但引用正確的行:第12行和將n2定義爲函數的行(而不是第24行)。這是一個編譯器錯誤?

+0

我已經testet這個代碼與各種編譯: VC++ 2015年不編譯並輸出錯誤的行號。 VC++ 2012和2013不編譯,但根本不輸出行號(候選人)。 gcc(各種版本)做編譯。 - 行號是錯誤的bug(似乎是VC++ 2015中的一個新功能),但我無法確定此代碼是否應該編譯。 –

+0

這裏沒有人可以爲你改變這一點。報告connect.microsoft.com上的錯誤和不需要的編譯器行爲 –

回答

2

我認爲微軟在這裏是正確的。競標工作的C++標準草案$7.3.4.6,它說

If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed....

然後,它提供了一種類似於你的,像這樣的例子:

namespace A { 
    class X { }; 
    extern "C" int g(); 
    extern "C++" int h(); 
} 
namespace B { 
    void X(int); 
    extern "C" int g(); 
    extern "C++" int h(int); 
} 
using namespace A; 
using namespace B; 

void f() { 
    X(1);    // error: name X found in two namespaces 
    g();    // OK: name g refers to the same entity 
    h();    // OK: overload resolution selects A::h 
} 

雖然,GCC和鐺接受的代碼。我認爲他們在這裏是錯誤的。

回到引用段落並注意行「...不宣佈同一個實體並且不聲明函數...」。

在您的代碼中,命名空間n1中的名稱n2是一個函數模板而不是函數。 因爲函數模板不是函數。見$8.3.5.15(重點煤礦):

A non-template function is a function that is not a function template specialization. [ Note: A function template is not a function. — end note ]

解決您的問題,有資格n2具有全局命名空間......這樣

namespace n1 
{ 
    template <class T> 
    void n2(); 

    template <class T> 
    void n2(T); 
} 

namespace n2 /* line 12 */ 
{ 
    class c {}; 
} 

using namespace n1; 

namespace n3 
{ 
    void foo(::n2::c); 
} 

void n3::foo(::n2::c) /* line 24 */ 
{ 

} 
相關問題