为什么不与Boost.Range工作ADL? [英] Why is ADL not working with Boost.Range?
问题描述
考虑到:
#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屋!