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

ZhangXiongpang zhangxiongpang at gmail.com
Thu Mar 7 23:28:13 PST 2013


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. Then I wrote three
tests, first two compiled failed, last one compiled ok. Maybe clang++ shall
support the first two cases.

Example 1:
------------------------------------------------------------
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);

int main() {
    X x;
    auto&& __range = x; // ok
    for ( auto __begin = begin(__range), __end = end(__range);
          __begin != __end; ++__begin ) {
        int i = *__begin;
        // ...
    } // ok
    for (int i : x) ; *// error: no viable 'begin' function available*
}
------------------------------------------------------------


Example 2:
------------------------------------------------------------
int count = 0;
struct X {};
struct Y {
    Y(const X&) { value = ++count; }
    Y(const Y&) { value = ++count; }
    int operator++() { return ++value; }
    int& operator*() { return value; }
    bool operator != (const Y& y) { return value != y.value; }
    int value;
};

typedef Y begin;
typedef Y end;

int main() {
    X x;
    auto&& __range = x; // ok
    for ( auto __begin = begin(__range), __end = end(__range);
          __begin != __end; ++__begin ) {
        int i = *__begin;
        // ...
    } // ok
    for (int i : x) ; *// error: no viable 'begin' function available*
}
------------------------------------------------------------


Example 3:
------------------------------------------------------------
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 X {
    struct Functor {
        Functor(int v) : value(v) {}
        Iterator operator()() { return Iterator(value); }
        int value;
    };
    Functor begin, end;
    X() : begin(1), end(5) {}
};

int main() {
    X x;
    auto&& __range = x; // ok
    for ( auto __begin = __range.begin(), __end = __range.end();
          __begin != __end; ++__begin ) {
        int i = *__begin;
        // ...
    } // ok
    for (int i : x) ; *// ok, very good!*
}
------------------------------------------------------------



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



More information about the cfe-dev mailing list