2011-03-22 121 views
5

这似乎有点倒退到我,但它的工作原理:为什么C++参数范围影响名称空间内的函数查找?

#include <iostream> 

namespace nTest 
{ 
    struct cTest {}; 

    void fTest(cTest& x) 
    { 
    std::cout << "nTest::fTest(cTest&) called" << std::endl; 
    } 
} 

int main(void) 
{ 
    nTest::cTest x; 
    fTest(x); //Weird! fTest is resolved since its parameter belongs to nTest. 
    return 0; 
} 

通常情况下,你需要NTEST ::才能访问FTEST,但属于NTEST它的参数似乎NTEST增加的可能名单在其中搜索fTest的范围。对我来说,参数范围影响函数查找似乎很奇怪。

这在GCC中编译得很好,但我想知道这种用法是否便携?这个范围界定机制的官方定义是什么?

+2

ADL - 参数依赖查找(http://en.wikipedia.org/wiki/Argument-dependent_name_lookup) – Nim 2011-03-22 14:21:20

+2

也读取接受的答案[here](http://stackoverflow.com/questions/2958648/what-are -the-pitfalls-of-adl) – 2011-03-22 14:23:24

回答

1

它的最初目的是找到重载运算符,如操作员< <用于发送一个字符串到std ::法院。如果我们没有ADL,那么您将不得不像这样编写代码:std::operator<<(std::cout, "nTest::fTest(cTest&) called")

不太好!

如果它适用于运营商,为什么不以同样的方式工作?

12

这是ADL(参数从属查找)或Koenig查找(用于该功能的设计者)。该功能的用途是,在许多情况下,相同的名称空间将包含可应用于这些类型的类型和功能,所有这些类型和功能都符合interface。如果ADL不在位,则必须使用using声明将标识符带入范围,否则您必须限定呼叫。

由于语言允许操作符重载,这成为一场噩梦。请看下面的例子:

namespace n { 
    struct test {}; 
    test operator+(test, test const &); // implemented 
}; 
int main() { 
    n::test a,b; 
    n::test c = a + b; //without ADL: c = n::operator+(a, b) 
} 

虽然它看起来像一个尴尬的局面,考虑到n可能是std命名空间,test可能是ostream,并operator+可能是operator<<

int main(int argc, char**) { 
    std::cout << "Hi there, there are " << argc << " arguments" << std::endl; 
} 

没有ADL ,operator<<的调用必须是明确的,而且您必须知道其中哪些实现为自由函数与方法。您是否知道std::cout << "Hi"正在呼叫免费功能,并且std::cout << 5正在呼叫成员功能?没有多少人意识到这一点,严肃地说,几乎没有人关心。 ADL隐藏了你的信息。