2011-07-18 55 views
11

我认为for_each是在标准名称空间中定义的,但是这个代码实际上是编译并且使用下面的编译器标志运行。有人可以解释为什么吗?为什么for_each没有std ::前缀

//@filename myprog.cpp 
    //g++-4.5 --std=c++0x myprog.cpp 

    #include<iostream> 
    #include<algorithm> 

    int main() 
    { 
    std::vector<int> v{1,2,3,4,5}; 
    std::cout<<"printing the number\n"; 
    for_each(v.begin(),v.end(),[](int num) {//no std::for_each 
     std::cout<<num<<"\t"; 
    }); 
return 0; 
} 
+5

查找ADL - 这个网站上有很多问题(参数依赖查找) – Nim

+0

我在想这不会是可移植的。我知道你只是好奇,但我建议使用'std ::'来保证安全。 –

+0

编译并运行哪个编译器和标准库实现? –

回答

15

将注释转换为答案,其工作原因是ADL(参数依赖查找)。基本上这意味着,如果在当前命名空间中找不到for_each的合适匹配项,编译器就会有一个内置规则,它说现在查看其他命名空间 - 并且它使用的命名空间的名称空间是参数。一旦它有一组命名空间,它将搜索它们以找到合适的for_each

问题仍然存在是否std::vector<>::iterator驻留在std::或不。很明显,在你的实现中它会这样做,这就是为什么找到合适的for_eachstd::。有可能是这种迭代器不在std:: - 为了安全起见(如艾伦的评论),总是养成与std::排位赛的习惯。

此外,这样可以防止任何其他人将另一个for_each(出于参数的原因)引入您的名称空间 - 这可能会破坏事情(在更糟的情况下 - 默默接受 - 但在运行时会中断)。

+0

感谢您的回答 –

+0

+1,因为我几个星期前才发现它,它仍令我惊叹;另外:这种功能的原因之一是允许自由函数操作符工作而不必指定任何名称空间。 “ – Klaim

+2

”在默认名称空间中找不到合适的匹配项“?我不认为ADL是这样工作的。如果“默认命名空间”会隐藏关联的命名空间,那么在命名空间中重载时会遇到问题。什么是默认的命名空间呢?你的意思是现在吗? – MSalters

相关问题