<div dir="ltr"><br><div>Hi all,</div><div><br></div><div>Please consider the following code which happens to be a gcc testsuite testcase:</div><div><br></div><div><br></div><div><div>struct iterator </div><div>{</div><div>
    int x;</div><div>    explicit iterator(int v) :x(v) {}</div><div>    iterator &operator ++() { ++x; return *this; }</div><div>    int operator *() { return x; }</div><div>    bool operator != (const iterator &o) { return x != o.x; }</div>
<div>};</div><div><br></div><div>// User defined container class</div><div>struct container </div><div>{</div><div>    int min, max;</div><div>    container(int a, int b) :min(a), max(b) {}</div><div>};</div><div><br></div>
<div>// Defintion of begin() and end() functions</div><div>namespace std</div><div>{</div><div>    iterator begin(container &c)</div><div>    {</div><div>        return iterator(c.min);</div><div>    }</div><div><br></div>
<div>    iterator end(container &c)</div><div>    {</div><div>        return iterator(c.max + 1);</div><div>    }</div><div>}</div><div><br></div><div>int main()</div><div>{</div><div>    container c(1,4);</div><div>    for (int it : c)</div>
<div>    {</div><div>    }</div></div><div>}</div><div><br></div><div>Compiling it with clang gives the following error:</div><div><br></div><div><div>range-for3.C:39:17: error: invalid range expression of type 'container'; no viable 'begin' function available</div>
<div>    for (int it : c)</div><div>                ^ ~</div><div>1 error generated.</div></div><div><br></div><div>clang version details: clang version 3.4 (trunk 186087)</div><div>Target: i386-pc-linux-gnu</div><div>Thread model: posix</div>
<div><br></div><div>My question is: Is it legal to define the begin() and end() functions in the namespace std scope? </div><div><br></div><div>The standard says: </div><div><br></div><div><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">
<font color="#000000" face="Arial, Liberation Sans, DejaVu Sans, sans-serif"><span style="font-size:14px;line-height:18px">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;</span></font></p>
<p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word"><span style="font-size:14px;line-height:18px;color:rgb(0,0,0);font-family:Arial,'Liberation Sans','DejaVu Sans',sans-serif;background-color:transparent">— 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.</span><br>
</p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word"><br></p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">
As far as I can make out the function defined in the file SemaStmt.cpp:</p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S,<span style="background-color:transparent">Expr *BeginRange, Expr *EndRange,</span><span style="background-color:transparent">QualType RangeType,</span><span style="background-color:transparent">VarDecl *BeginVar,</span><span style="background-color:transparent">VarDecl *EndVar,</span><span style="background-color:transparent">SourceLocation ColonLoc,</span><span style="background-color:transparent">OverloadCandidateSet *CandidateSet,</span><span style="background-color:transparent">ExprResult *BeginExpr,</span><span style="background-color:transparent">ExprResult *EndExpr,</span><span style="background-color:transparent">Sema::BeginEndFunction *BEF);</span></p>
<p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word"><span style="background-color:transparent"><br></span></p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">
<span style="background-color:transparent">is responsible for locating the appropriate match for begin() and end() function definitions.</span></p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">
Is there a bug somewhere here or am I missing something?</p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">Any input on the same would be helpful.</p>
<p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word"><br></p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">
Thanks,</p><p style="margin:0px 0px 1em;padding:0px;border:0px;vertical-align:baseline;background-color:transparent;clear:both;word-wrap:break-word">Rahul</p></div></div>