[cfe-dev] Range for loop and namespace std
Rahul Jain
1989.rahuljain at gmail.com
Fri Sep 13 14:23:19 PDT 2013
Thanks Richard :)
On Sat, Sep 14, 2013 at 2:51 AM, Richard Smith <richard at metafoo.co.uk>wrote:
> On Fri, Sep 13, 2013 at 1:58 PM, Rahul Jain <1989.rahuljain at gmail.com>wrote:
>
>> Thanks Richard and James for the quick revert.
>> This resolution of the standard makes things clearer.
>>
>> So best practice would be to define begin() and end() as member functions
>> of the user defined container class right?
>>
>
> 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.
>
>
>> On Sat, Sep 14, 2013 at 2:04 AM, Richard Smith <richard at metafoo.co.uk>wrote:
>>
>>> On Fri, Sep 13, 2013 at 1:19 PM, Rahul Jain <1989.rahuljain at gmail.com>wrote:
>>>
>>>>
>>>> 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);
>>>> }
>>>>
>>>
>>> This has undefined behavior. You can't add new declarations to namespace
>>> std.
>>>
>>> iterator end(container &c)
>>>> {
>>>> return iterator(c.max + 1);
>>>> }
>>>> }
>>>>
>>>> int main()
>>>> {
>>>> container c(1,4);
>>>> for (int it : c)
>>>> {
>>>>
>>>
>>> This test is wrong, per DR1442:
>>>
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442
>>>
>>>
>>>> }
>>>> }
>>>>
>>>> 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?
>>>>
>>>
>>> No. See 17.6.5.2.1/1:
>>>
>>> "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."
>>>
>>> (The "unless otherwise specified" cases don't apply here.)
>>>
>>>
>>>> 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.
>>>>
>>> It does not say this any more :)
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130914/1c6e4250/attachment.html>
More information about the cfe-dev
mailing list