[cfe-dev] Range for loop and namespace std

Rahul Jain 1989.rahuljain at gmail.com
Fri Sep 13 13:19:02 PDT 2013


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130914/a5838f2e/attachment.html>


More information about the cfe-dev mailing list