2011-05-12 68 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