Boost logo

Boost Users :

Subject: Re: [Boost-users] ambiguity between std::begin/end and boost::begin/end in gcc 4.6
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2010-12-27 15:00:39


> From: neil_at_[hidden]
> To: boost-users_at_[hidden]
> Subject: Re: [Boost-users] ambiguity between std::begin/end and
> boost::begin/end in gcc 4.6
>
> However in this case I have yet to understand the nature of the
> underlying problem, because there isn't an obvious unqualified call to
> begin/end. The reverse adaptor uses qualified calls that can't possibly
> be ambiguous with std::begin/end. I haven't yet checked to see if
> unqualified calls to begin/end are intended to be used as an extension
> mechanism for the next C++ standard.

The unqualified call to begin/end comes from the range-based for loop.
 
Quoting from the C++0x Standard Section 6.5.4
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3225.pdf):
 
------------------------------------------------------------------------
For a range-based for statement of the form
for ( for-range-declaration : expression ) statement
let range-init be equivalent to the expression surrounded by parentheses:89
( expression )
and for a range-based for statement of the form
for ( for-range-declaration : braced-init-list ) statement
let range-init be equivalent to the braced-init-list.
In each case, a range-based for statement is equivalent to

{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
             __end = end-expr;
        __begin != __end;
        ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}

where __range, __begin, and __end are variables defined for exposition only,
and _RangeT is the type of the expression, and begin-expr and end-expr are
determined as follows:.

— if _RangeT is an array type, begin-expr and end-expr are __range and
  __range + __bound, respectively, where __bound is the array bound.
  If _RangeT is an array of unknown size or an array of incomplete type,
  the program is ill-formed.

— otherwise, begin-expr and end-expr are begin(__range) and end(__range),
  respectively, where begin and end are looked up with argument-dependent
  lookup (3.4.2). For the purposes of this name lookup, namespace std is
  an associated namespace.
------------------------------------------------------------------------
 
So "std" is an associated namespace because the standard says so, and
"boost" is an associated namespace because the type being iterated
over is boost::reverse_range<T>, and so ADL finds both std::begin/end
and boost::begin/end.
 
Regards,
Nate.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net