【问题标题】:Why is std::generate accessible without namespace qualifier?为什么 std::generate 可以在没有命名空间限定符的情况下访问?
【发布时间】:2016-04-04 14:56:10
【问题描述】:

这样编译正常吗?

#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++,所以可能是库错误?

【问题讨论】:

  • AFAIK - 是的,这是可以接受的,因为在同一命名空间 (std) 中定义了一个类型 std::vector
  • @soon:未指定迭代器类型是否存在于命名空间std 中。如果迭代器类型只是一个裸指针,那么这是行不通的。特别是,行为可能取决于您是在调试模式还是优化模式下编译。

标签: c++ c++11 gcc namespaces clang


【解决方案1】:

这是允许的,主要是因为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

【讨论】:

  • 不能保证参数(向量迭代器)在namespace std 中。所以这可能无法在某些平台/配置上编译。
  • 调用generate时,将在所有参数类型的命名空间中搜索名称generate(x, y, f); 在函数名搜索开始之前从参数中获取命名空间。
猜你喜欢
  • 2021-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
相关资源
最近更新 更多