c++ - Why cannot use iterator in range-base for? -
i'm trying iterate std::list , work each of elements, , maybe remove of them. remove element, using erase function should faster using remove function, need iterate iterator. think range-base can me doesn't. seems me (maybe many others) c++11 range-based using iterator. , have check cppreference.com says
for ( range_declaration : range_expression ) loop_statement
will give
{ auto && __range = range_expression ; (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) { range_declaration = *__begin; loop_statement } }
where begin_expr
__range.begin()
. have tried code:
typedef std::list<int> intlist; intlist i; (intlist::iterator : i) { }
and not compile. if changed to
typedef std::list<int> intlist; intlist i; (int : i) { }
it works well. think range-based not using iterators (that is, not begin function), using else. why cannot?
i have tried code on visual c++ 2013 ctp , g++.
edit
yes, didn't notice '*'. operator* called, can not use iterator more. that's fault.
another question whether can use erase of std::list during iterating. again it's fault. after thinking again, way use ordinary , before remove, iterator next element. in fact told not modify container when iterating, misunderstood reference says iterator of list still valid after modification container. i'll find other way it. anyway, thank remind! @theolodis
note line:
range_declaration = *__begin;
here, dereference hidden iterator, , assign value mutable part of statement.
the iterator (the result of begin(__range)
, end(__range)
) hidden you. compiler create variables in background not visible you. see result of *__begin
. in case, value_type
of container, int
.
additionally, modifying container while iterating on quite dangerous, make sure read on iterator invalidation (which applies range loop).
the usual way erase container in c++ use erase-remove idiom. in c++11, if, example, wanted remove numbers.
intlist i; auto is_even = [](int arg) -> bool { return arg % 2 == 0; }; i.erase(std::remove_if(i.begin(), i.end(), is_even), i.end());
Comments
Post a Comment