为什么不与Boost.Range工作ADL? [英] Why is ADL not working with Boost.Range?

查看:165
本文介绍了为什么不与Boost.Range工作ADL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑到:

#include <cassert>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm.hpp>

int main() {
    auto range = boost::irange(1, 4);
    assert(boost::find(range, 4) == end(range));
}

<大骨节病>现场演示锵
<大骨节病>现场演示GCC

这给出了:

main.cpp中:8:37:错误:使用未声明的标识符结束的

main.cpp:8:37: error: use of undeclared identifier 'end'

考虑到如果你写使用boost ::结束; 工作得很好,这意味着的boost ::结束是可见的:

Considering that if you write using boost::end; it works just fine, which implies that boost::end is visible:

为什么ADL没有工作,在EX pression找到的boost ::结束 端(范围)?而如果是故意的,什么是理落后吗?

Why is ADL not working and finding boost::end in the expression end(range)? And if it's intentional, what's the rationale behind it?

需要明确的是,预期的结果将是类似于这个例子使用的std :: find_if 和不合格端(VEC)

To be clear, the expected result would be similar to what happens in this example using std::find_if and unqualified end(vec).

推荐答案

升压/范围/ end.hpp 他们明确通过把结束块中的ADL range_adl_barrier 命名空间,然后使用命名空间range_adl_barrier ; 来把它纳入升压命名空间。

In boost/range/end.hpp they explicitly block ADL by putting end in a range_adl_barrier namespace, then using namespace range_adl_barrier; to bring it into the boost namespace.

由于结束实际上并没有从 ::提升,而是来自 ::提高:: range_adl_barrier ,它不是由ADL找到。

As end is not actually from ::boost, but rather from ::boost::range_adl_barrier, it is not found by ADL.

提振/range/begin.hpp :

Their reasoning is described in boost/range/begin.hpp:

//使用ADL命名空间障碍,以避免与其他不合格结果,模糊
  //调用。这是一个用C ++ 0x中令人鼓舞的结果尤为重要
  //调用不合格的开始/结束。

// Use a ADL namespace barrier to avoid ambiguity with other unqualified
// calls. This is particularly important with C++0x encouraging
// unqualified calls to begin/end.

没有例子给出的,其中这将导致一个问题,所以我只能推论他们在说什么。

no examples are given of where this causes a problem, so I can only theorize what they are talking about.

下面是一个例子,我已经发明了ADL如何引起歧义:

Here is an example I have invented of how ADL can cause ambiguity:

namespace foo {
  template<class T>
  void begin(T const&) {}
}

namespace bar {
  template<class T>
  void begin(T const&) {}

  struct bar_type {};
}

int main() {
  using foo::begin;
  begin( bar::bar_type{} );
}

活生生的例子。无论 :: foo的开始酒吧::开始同样有效调用的函数为开始(巴:: bar_type {})在这种情况下。

live example. Both foo::begin and bar::begin are equally valid functions to call for the begin( bar::bar_type{} ) in that context.

这可能是他们在说什么。他们的的boost ::开始的std ::开始可能是在你有一个背景下同样有效使用的std ::开始上一个类型从升压。通过将它的子空间升压的std ::开始被调用(和工作在范围内,自然)。

This could be what they are talking about. Their boost::begin and std::begin might be equally valid in a context where you have using std::begin on a type from boost. By putting it in a sub-namespace of boost, std::begin gets called (and works on ranges, naturally).

如果在开始命名空间中的升压已经不太通用,这将是preferred,但是不是他们是如何写的。

If the begin in the namespace boost had been less generic, it would be preferred, but that isn't how they wrote it.

这篇关于为什么不与Boost.Range工作ADL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆