2011-05-12 77 views
5

我對C++中的標準ADL分辨率有疑問。帶模板功能的嵌套命名空間中的C++ ADL

下面是一個示例代碼解釋我的詢問:

#include <string> 

// The mechanism: 
namespace A { 

template< class C > 
::std::string scope(const C*) 
{ return "A"; } 

namespace B { 

    template< class C > 
    ::std::string scope(const C *foo) 
    { return A::scope(foo)+"::B"; } 

} // namespace B 
} // namespace A 

::std::string scope(...) 
{ return ""; } 

// The test classes 
struct foo {}; 
namespace A { 
struct foo {}; 
namespace B { 
    struct foo {}; 
} 
} 

// The usage 
int main() 
{ 
    foo *Foo=0; 
    A::foo *FooA=0; 
    A::B::foo *FooB=0; 

    scope(Foo); // OK, returns "" 
    scope(FooA); // OK, returns "A" 
    scope(FooB); // On one compiler, OK returns "A::B" ; On another, compiler error "Ambiguous call" between A::scope() and A::B::scope() 
} 

所以,我的問題是什麼是關於ADL的標準? 應該找到參數的父命名空間中的所有函數,還是隻有參數(嵌套)名稱空間中可用的函數+全局函數?

這個程序已經過測試,於2008年MSVC(與SP編譯但不能沒有...)

+0

你的代碼甚至不會在任何編譯器上編譯,因爲不帶參數的'A :: scope()'不存在,但你可以調用這個函數。 – Nawaz 2011-05-12 09:20:37

+0

一個編譯器老舊,另一個是新的,還是來自不同的製造商? – 2011-05-12 09:25:25

+0

@Nawaz - >編輯... – DocZeD 2011-05-12 11:19:33

回答

5

根據標準,ADL作品(模一對夫婦的特殊規則) 「好像」功能名稱之前是名稱空間;在您最後的 行中,查找應先於您寫作A::B::scope。其中 沒有看到周圍的命名空間。

請注意,即使在命名空間A::B內,也不會有歧義;在 A::B,A::B::scope隱藏A::scope。非限定名稱查找在第一次找到名稱的範圍內停止 。

+0

謝謝詹姆斯,這正是我的想法:) 所以要恢復,我的代碼應該編譯時不會有任何由模糊造成的編譯器錯誤...再次從MSVC符合標準的問題不是它:/ – DocZeD 2011-05-12 11:23:12

+0

@DocZeD只是好奇,但什麼VC的版本? – 2011-05-12 15:18:14

+0

工作:15.00.30729.01 - 不工作:15.00.21022.08 – DocZeD 2011-05-12 17:59:58