Hi all,
Please consider the following code which happens to be a gcc testsuite testcase:
struct iterator
{
int x;
explicit iterator(int v) :x(v) {}
iterator &operator ++() { ++x; return *this; }
int operator *() { return x; }
bool operator != (const iterator &o) { return x != o.x; }
};
// User defined container class
struct container
{
int min, max;
container(int a, int b) :min(a), max(b) {}
};
// Defintion of begin() and end() functions
namespace std
{
iterator begin(container &c)
{
return iterator(c.min);
}
iterator end(container &c)
{
return iterator(c.max + 1);
}
}
int main()
{
container c(1,4);
for (int it : c)
{
}
}
Compiling it with clang gives the following error:
range-for3.C:39:17: error: invalid range expression of type ‘container’; no viable ‘begin’ function available
for (int it : c)
^ ~
1 error generated.
clang version details: clang version 3.4 (trunk 186087)
Target: i386-pc-linux-gnu
Thread model: posix
My question is: Is it legal to define the begin() and end() functions in the namespace std scope?
The standard says:
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) and end(__range), respectively, where begin and end are looked up with argument-dependent lookup (3.4.2). For the purposes of this name lookup, namespace std is an associated namespace.
As far as I can make out the function defined in the file SemaStmt.cpp:
static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S,Expr *BeginRange, Expr *EndRange,QualType RangeType,VarDecl *BeginVar,VarDecl *EndVar,SourceLocation ColonLoc,OverloadCandidateSet *CandidateSet,ExprResult *BeginExpr,ExprResult *EndExpr,Sema::BeginEndFunction *BEF);
is responsible for locating the appropriate match for begin() and end() function definitions.
Is there a bug somewhere here or am I missing something?
Any input on the same would be helpful.
Thanks,
Rahul