J
Johannes Schaub (litb)
Range-based for loop description says 6.5.4/1:
"... begin-expr and end-expr are begin(__range) and end(__range),
respectively, where begin and end are looked up with argument-dependent
lookup (3.4.2)."
And 3.4.2 says at 3.4.2/3:
"Let X be the lookup set produced by unqualiï¬ed lookup (3.4.1) and let Y be
the lookup set produced by argument dependent lookup (deï¬ned as follows). If
X contains
- a declaration of a class member, or
- a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function or a function template
then Y is empty. Otherwise Y is the set of declarations found in the
namespaces associated with the argument types as described below. The set of
declarations found by the lookup of the name is the union of X and Y"
WTF!? Now is the following code valid? I.e is the set of declarations found
the union of X and Y or is it only Y?!
struct Foo {
typedef int *iterator;
int *begin() { return array; }
int *end() { return array + 2; }
int array[2];
};
namespace ranges {
template<typename T>
typename T::iterator begin(T &t) { return t.begin(); }
template<typename T>
typename T::iterator end(T &t) { return t.end(); }
}
int main() {
// Is "X" included in the set of declarations found!?
using ranges::begin;
using ranges::end;
Foo f = { 1, 2 };
for(int a : f)
;
}
"... begin-expr and end-expr are begin(__range) and end(__range),
respectively, where begin and end are looked up with argument-dependent
lookup (3.4.2)."
And 3.4.2 says at 3.4.2/3:
"Let X be the lookup set produced by unqualiï¬ed lookup (3.4.1) and let Y be
the lookup set produced by argument dependent lookup (deï¬ned as follows). If
X contains
- a declaration of a class member, or
- a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function or a function template
then Y is empty. Otherwise Y is the set of declarations found in the
namespaces associated with the argument types as described below. The set of
declarations found by the lookup of the name is the union of X and Y"
WTF!? Now is the following code valid? I.e is the set of declarations found
the union of X and Y or is it only Y?!
struct Foo {
typedef int *iterator;
int *begin() { return array; }
int *end() { return array + 2; }
int array[2];
};
namespace ranges {
template<typename T>
typename T::iterator begin(T &t) { return t.begin(); }
template<typename T>
typename T::iterator end(T &t) { return t.end(); }
}
int main() {
// Is "X" included in the set of declarations found!?
using ranges::begin;
using ranges::end;
Foo f = { 1, 2 };
for(int a : f)
;
}