<div dir="ltr">Thanks Richard :)</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Sep 14, 2013 at 2:51 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:58 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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></blockquote><div><br></div></div><div>The best practice would be to define these functions as member functions if that makes sense, and as free functions in the enclosing namespace (so they can be found by ADL) otherwise.</div>
<div><div class="h5">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div class="gmail_extra"><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>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>
<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><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><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><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>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>