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

ZhangXiongpang zhangxiongpang at gmail.com
Fri Mar 8 16:09:46 PST 2013


James Dennett wrote
> On Fri, Mar 8, 2013 at 2:37 PM, ZhangXiongpang <

> zhangxiongpang@

> > wrote:
>> James Dennett wrote
>>> On Fri, Mar 8, 2013 at 2:32 AM, ZhangXiongpang <
>>
>>> zhangxiongpang@
>>
>>> > wrote:
>>>> James Dennett wrote
>>>>>> In case (1), where "begin" and "end" are looked up as class members,
>>>>>> C++ doesn't allow the syntax object.TypeName,
>>>>
>>>> I know C++ doesn't allow the syntax "object.TypeName",
>>>> but the "object"(__begin) is a also a function object,
>>>> it is callable. so why not treat the object as a function?
>>>
>>> I'm sorry, I don't understand your question.  Are you talking about
>>> the case of your test (3), which compiles successfully (as it should),
>>> or something else?
>>
>> I mean in example 1 "begin" and "end" are also callable, just like the
>> "begin" and "end" in example 3. The difference between example 1 and
>> example
>> 3 is:
>> (1) in example 3, there is a member who named "begin" in class X, so it
>> will
>> look up "x.begin()" and "x.end()", standard says "begin-expr and end-expr
>> are __range.begin() and __range.end(), respectively".
> 
> Right, this is why (3) compiles.
> 
>> (2) in example 1, no member named "begin" or "end" in class X, so it will
>> look up "begin(x)" from the associated namespace of x, standard syas
>> "begin-expr and end-expr are begin(__range) and end(__range),
>> respectively".
> 
> The standard says that the lookup for name names "begin" and "end" is
> ADL in the non-member case, and so the non-functions begin and end are
> not found, and the code is erroneous.
> 
> Here's a modified example showing that the hand-written loop fails in
> the same way if restricted to using ADL + namespace std.
> 
> struct X {};
> struct Iterator {
>     Iterator(int v) : value(v) {}
>     int operator++(){ return ++value; }
>     int& operator*(){ return value; }
>     bool operator!=(const Iterator& iter) { return value != iter.value; }
>     int value;
> };
> struct Functor {
>     Functor(int v) : value(v) {}
>     Iterator operator()(const X&) { return Iterator(value); }
>     int value;
> };
> 
> Functor begin(1), end(5);
> 
> namespace std {
> int *begin(int*);
> int *end(int*);
> }
> 
> int main() {
>   using std::begin;
>   using std::end;
> 
>     X x;
>     auto&& __range = x; // ok
>     for ( auto __begin = begin(__range),  // error: no matching
> function for call to 'begin'
>           __end = end(__range);
>           __begin != __end; ++__begin ) {
>         int i = *__begin;
>         // ...
>     } // ok
>     for (int i : x) ; *// error: no viable 'begin' function available*
> }
> 
> Note that the manually lowered loop fails to compile, for the same
> reason as the range-based one: no suitable "begin" is found.

I understand. Thanks very much for you answer.




--
View this message in context: http://clang-developers.42468.n3.nabble.com/clang-c-11-complier-problems-about-ranged-based-for-tp4030863p4030899.html
Sent from the Clang Developers mailing list archive at Nabble.com.



More information about the cfe-dev mailing list