[cfe-dev] [clang++][c++11] complier problems about "ranged-based for"

James Dennett james.dennett at gmail.com
Thu Mar 7 23:51:52 PST 2013

On Thu, Mar 7, 2013 at 11:28 PM, ZhangXiongpang
<zhangxiongpang at gmail.com> wrote:
> Platform: linux, x86_64, clang++3.2
> 6.5.4/p1:
> ------------------------------------------------------------
> 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
>       }
>   }
> ------------------------------------------------------------
> The begin-expr and end-expr have two cases if _RangeT is not an array type:
> (1) begin-expr and end-expr are __range.begin() and __range.end(),
> respectively
> (2) begin-expr and end-expr are begin(__range) and end(__range),
> respectively
> Standard doesn't say whether "begin" and "end" must be an function, so I
> think they can also be function objects or class names.

I think that the Standard is clear on this (well, as clear as it ever
is), and that Clang appears to implement this correctly.

In case (1), where "begin" and "end" are looked up as class members,
C++ doesn't allow the syntax object.TypeName, so the only interesting
case is your example 3, where range.begin and range.end are callable
data members.  As your tests show, Clang permits that.

In case (2), "begin" and "end" are found via argument-dependent
lookup, which only finds function (and function template) names.  You
can add "using std::begin; using std::end;" inside your functions that
emulate range-based "for" to prevent finding the globals via non-ADL
lookup and more accurately emulate the semantics of range-based for
(and hence will not compile).

-- James

More information about the cfe-dev mailing list