<div dir="ltr">Thanks Richard and James for the quick revert.<div>This resolution of the standard makes things clearer.</div><div><br></div><div>So best practice would be to define begin() and end() as member functions of the user defined container class right?</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Sep 14, 2013 at 2:04 AM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="im">On Fri, Sep 13, 2013 at 1:19 PM, Rahul Jain <span dir="ltr"><<a href="mailto:1989.rahuljain@gmail.com" target="_blank">1989.rahuljain@gmail.com</a>></span> wrote:<br>
</div><div class="gmail_extra"><div class="gmail_quote"><div class="im">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><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></div>

</blockquote><div><br></div></div><div>This has undefined behavior. You can't add new declarations to namespace std.</div><div class="im"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><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></blockquote><div><br></div></div><div>This test is wrong, per DR1442:</div><div><br></div><div><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442</a><br>

</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><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></blockquote><div><br></div></div><div>No. See 17.6.5.2.1/1:</div><div><br></div><div><div>
"The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified."</div>
</div><div><br></div><div>(The "unless otherwise specified" cases don't apply here.)</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<div dir="ltr"><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="line-height:18px;font-size:14px;background-color:transparent;font-family:Arial,'Liberation Sans','DejaVu Sans',sans-serif">— 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></p>

</div></div></blockquote></div><div>It does not say this any more :)</div></div></div></div>
</blockquote></div><br></div>