为什么可以在没有命名空间限定符的情况下访问std::generate函数?

9

这个编译通过是正常的吗?

#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> buf;
    generate(buf.begin(), buf.end(), []{ return 0; });
}

请注意,在generate()前面缺少了std::

这种行为有文档记录吗?或者我是偶然发现了编译器或库的错误?在我的情况下,使用的是Linux上的GCC 5.3.0和Clang 3.8.0,两者都使用libstdc++,因此可能是库的错误?


5
"Argument-dependent lookup" 是指参数相关的名称查找。 - zwol
AFAIK - 是的,这是可以接受的,因为类型 std::vector 在同一命名空间 (std) 中定义。 - awesoon
6
未明确迭代器类型是否位于命名空间 std 中。如果迭代器类型只是一个裸指针,则无法工作。特别地,行为可能取决于您是在调试模式还是优化模式下编译。 - Kerrek SB
1个回答

3

这是允许的,因为generate的参数在std中。

像这样的代码

namespace Foo
{
    struct B{};
    void foo(const B&);
}

int main()
{
    Foo::B b; /*Requires Foo::*/
    foo(b); /*Does not require Foo:: as that is gleaned from the argument*/
}

出于类似的原因,使用参数相关查找也是可以接受的。请参见https://en.wikipedia.org/wiki/Argument-dependent_name_lookup


7
不能保证参数(向量迭代器)在namespace std中,因此在某些平台/配置上可能无法编译通过。 - interjay
2
当您调用 generate(x, y, f); 时,所有参数类型的命名空间都将被搜索以查找名称为 generate 的函数。在函数名搜索开始之前,命名空间取自参数。 - Richard Hodges

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