【问题标题】:Why some Boost functions don't need prefixing with namespace为什么某些 Boost 函数不需要以命名空间为前缀
【发布时间】:2016-02-01 09:55:42
【问题描述】:

考虑一下这段代码(或live example):

#include <iostream>

#include <boost/graph/adjacency_list.hpp>
#include <boost/range/iterator_range.hpp>

using std::cout;

int main() {
  boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS> g;

  add_edge(0, 1, g);
  add_edge(1, 2, g);

  for(auto v : make_iterator_range(vertices(g))) {
    cout << v << " has " << degree(v, g) << " neighbor(s): ";
    for(auto w : make_iterator_range(adjacent_vertices(v, g))) cout << w << ' ';
    cout << '\n';
  }
  return 0;
}

为什么来自 Boost 库的函数 add_edgemake_iterator_rangeverticesdegreeadjacent_vertices 在没有 boost:: 命名空间前缀的情况下也能工作?

最让我不解的是,视情况而定,有时实际上需要前缀。 Here is an example,当使用不同的图形结构时会导致编译错误,可以通过前缀 boost::make_iterator_range 来修复。

我在BGL documentation 周围看了一些,但没有找到任何关于这个问题的信息。是我的错还是某些 BGL 标头污染了全局命名空间?这是设计使然还是错误?

【问题讨论】:

  • 依赖于参数的查找 (ADL),又名 Koenig 查找(在 Andrew Koenig 之后)。
  • 我重新提出这个问题是因为有人可能想详细解释一下,为什么链接的代码无法编译
  • 尽管还有其他关于 ADL 的问题(很难找到,尤其是不搜索 ADL 一词),但这是一个问得非常好的问题。可以改进的主要事情是所有命名空间都会发生这种情况,而不是 Boost,但我可以看过去而不点击尝试。
  • 啊,根据文档,vertices 返回一个std::pair,所以make_iterator_range 确实需要资格。但是,您没有资格的其他人都可以编译。看起来ideone的GCC版本在那里有一个错误。 5.2 不编译。
  • @chris 我认为如果 std::pair 的类型模板参数来自 boost 的命名空间,那么 ADL 仍然会发生

标签: c++ boost boost-graph argument-dependent-lookup


【解决方案1】:

它与boost无关,但与任何namespace有关。

使用argument-dependent lookup (ADL),参数中的命名空间被添加到重载搜索中。

例如:

add_edge(0, 1, g);

g 来自命名空间boost,因此我们也在命名空间boost 中寻找add_edge

【讨论】:

  • 我认为这并不能真正解释为什么 OP 链接的其他代码示例无法编译。
  • @ChristianHackl:在失败的代码中,vertices(g) 返回一个std::pair&lt;std::list&lt;void*&gt;::iterator, std::std::list&lt;void*&gt;::iterator&gt;(没有来自boost),所以make_iterator_range 只在全局和std 命名空间中搜索。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2018-03-26
  • 2012-09-29
  • 2015-02-10
  • 1970-01-01
  • 2020-08-07
相关资源
最近更新 更多