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
_RangeT
is an array type, begin-expr and end-expr are__range
and__range + __bound
, respectively, where__bound
is the array bound. If_RangeT
is an array of unknown size or an array of incomplete type, the program is ill-formed;- if
_RangeT
is a class type, the unqualified-ids begin and end are looked up in the scope of class_RangeT
as 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, wherebegin
andend
are 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