Consider the specification of the range-based for loop's begin-expr and end-expr (N4140 [stmt.ranged]/p1). Given a range __range of type _RangeT,
begin-expr and end-expr are determined as follows:
- if
_RangeTis an array type, begin-expr and end-expr are__rangeand__range + __bound, respectively, where__boundis the array bound. If_RangeTis an array of unknown size or an array of incomplete type, the program is ill-formed;- if
_RangeTis a class type, the unqualified-ids begin and end are looked up in the scope of class_RangeTas if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration, begin-expr and end-expr are__range.begin()and__range.end(), respectively;- otherwise, begin-expr and end-expr are
begin(__range)andend(__range), respectively, wherebeginandendare looked up in the associated namespaces (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1) is not performed. —end note ]
Is it possible to simulate this exact behavior in ordinary C++ code? i.e., can we write a magic_begin and a magic_end function template such that
for(auto&& p : range_init) { /* statements */ }
and
{
auto&& my_range = range_init;
for(auto b = magic_begin(my_range), e = magic_end(my_range); b != e; ++b){
auto&& p = *b;
/* statements */
}
}
always have the exact same behavior?
Non-answers include qualified calls to std::begin/std::end (doesn't handle the third bullet, among other things) and using std::begin; begin(range); because, among other things, that is ambiguous if ADL for begin finds an overload that's equally good as std::begin.
Aucun commentaire:
Enregistrer un commentaire