STL算法函数名称解析

17

我期望在下面的例子中,编译器无法编译代码,因为它不知道什么是“find()”,而此函数在algorithm头文件的std命名空间中被定义。

然而,这段代码在使用gcc 4.1.2编译器时可以在RHEL 5.3上编译通过。

我错过了什么吗?

#include <string>    
#include <algorithm>

int main()
{
    std::string s;
    find(s.begin(), s.end(), 'a');  // should not compile
}

@Nick:不是。请看下面的答案。 - Jan Hudec
请参阅https://dev59.com/ElLTa4cB1Zd3GeqPXyzq和http://msdn.microsoft.com/en-us/library/60bx1ys7.aspx。 - Marius Bancila
1个回答

27

这个方法的工作原理是通过参数依赖查找(Argument Dependent Lookup)实现的。函数模板会在参数类型的命名空间中被搜索。在本例中,参数是 std::string::iterator,所以函数会在命名空间std中被搜索。


2
Aka Koenig查找。Dimba:如果你想要证明这一点,可以看到::find不会在全局命名空间中匹配,在给定char a[1]的情况下,find(&a[0], &a[0],'a')将无法找到std::find()模板... - Tony Delroy
6
为了阐述ADL的存在原因,“主要”的理由是让运算符能够自然地工作。给定两个std::string对象s1s2,您希望能够使用s1 + s2将它们连接起来。如果没有ADL,您将不得不编写std::operator+(s1, s2)。但是事实证明,这也是其他情况下非常有用的机制。 - jalf
@jalf: 这个示例真的没问题吗?就我所见(今晚并不太清醒——必须停止玩愚蠢的游戏直到凌晨4点),一个全局的 ::operator+(const std::string&, const std::string&) 无论如何都可以匹配。因此,更重要的是找到正确的 find(),尽管在调用代码相关的介入命名空间中有其他无关的 find() - Tony Delroy
@mister:抱歉,但我无法在那方面帮助你。 - Björn Pollex
@Tony:没错,但我的观点只是标准库通常会将所有内容放在std命名空间中,如果突然决定“嘿,让我们把所有运算符重载放在全局命名空间中”,这似乎非常不一致,并且随着现代IDE提供的智能感知和自动完成功能,这将不必要地使全局命名空间变得混乱。 - jalf
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接