[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