Topic: No cbegin/cend for std::initializer_list?


Author: Hyman Rosen <hyrosen@mail.com>
Date: Mon, 21 Sep 2009 18:26:04 CST
Raw View
Tony wrote:
> Concrete example:  Windows HWND do not have 'next()' functions, you need
> to use GetNextWindow().  So my code that iterates over
>     "things that have next() member functions"
> can't iterate over HWNDs, but my code that iterates over
>     "things that work with free function: next(thing)"
> can, if I just write
> HWND next(HWND hwnd)
> {
>    return GetNextWindow(hwnd);
> }

That's why C# implemented extension methods. Then you can write
     HWND next(this HWND hwnd) { return GetNextWindow(hwnd); }
and now *both* versions of your iteration code work!

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <smeyers@aristeia.com>
Date: Tue, 1 Sep 2009 12:39:58 CST
Raw View
The initializer_list spec in N2914 provides iterators via begin/end,
but it fails to offer cbegin/cend.  There is no loss of functionality
here, because begin/end return const_iterators, but offering
cbegin/cend would make it easier to write generic code and would
encourage people to develop a habit of using cbegin/cend when they
perform iterators that don't mutate the elements being iterated over.
 Is there a reason not to add cbegin/cend to iterator_list?

As an aside, iterator list declares typedefs for iterator and
const_iterator, but it doesn't use them in the specification of
begin/end, which are spec'd to return raw pointers.  This seem, um,
less than ideal.

Scott


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Tue, 1 Sep 2009 23:14:50 CST
Raw View
On 1 Sep, 22:39, Scott Meyers <smey...@aristeia.com> wrote:
> but offering cbegin/cend would make it easier to write generic code

I think that generic code should use more general approach. N2930
proposes functions "begin" and "end" to be added to namespace std. I
think, there shall be also "cbegin", "cend", "rbegin", "rend",
"crbegin", and "crend" versions. Supposed std::cbegin can be applied
to built-in arrays in the same manner as to class-containers, and it
can work fine with old containers those don't have member function
"cbegin". IMHO, direct use of container's member "cbegin" in generic
code is bad idea.

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Philipp M." <bootsarehax@googlemail.com>
Date: Wed, 2 Sep 2009 11:38:05 CST
Raw View
On Sep 2, 7:14 am, Nikolay Ivchenkov <ts...@mail.ru> wrote:
> IMHO, direct use of container's member "cbegin" in generic
> code is bad idea.

Could you outline a few situations were usage of the members might
lead to unexpected problems afterwards?
I'm curious because I can't see such a situation (as I'm rather
inexperienced).

Philipp


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Nikolay Ivchenkov <tsoae@mail.ru>
Date: Wed, 2 Sep 2009 17:42:08 CST
Raw View
On 2          , 21:38, "Philipp M." <bootsare...@googlemail.com> wrote:
> Could you outline a few situations were usage of the members might
> lead to unexpected problems afterwards?

This approach will not work properly with old-style classes those
represent ranges. Furthermore, if we are talking about the use of
std::initializer_list, we should note that std::initializer_list is
simple kind of range (it is not a container). In general, range can be
represented by built-in array, pair of iterators packed in std::pair
or std::tuple, container, std::initializer_list, or other special
range-class. Well-designed generic code, that works with an abstract
range, should support all these categories. Direct use of member
"cbegin" will entail pointless limitations on use of such code.


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Ed Smith-Rowland <3dw4rd@verizon.net>
Date: Thu, 3 Sep 2009 13:09:03 CST
Raw View
While it is true that initializer_list is not really a container there
is a consistency of access issue.  There is something to be said for
minimizing surprises especially for novices.

I thought the original rationale for cbegin, etc. was to help type
deduction with auto.  While it certainly is not the best generic
programming practice to loop through an initializer list explicitly I
would say - "never say never".

Ed

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Tony <gottlobfrege@gmail.com>
Date: Mon, 21 Sep 2009 13:21:42 CST
Raw View
Philipp M. wrote:
> On Sep 2, 7:14 am, Nikolay Ivchenkov <ts...@mail.ru> wrote:
>> IMHO, direct use of container's member "cbegin" in generic
>> code is bad idea.
>
> Could you outline a few situations were usage of the members might
> lead to unexpected problems afterwards?
> I'm curious because I can't see such a situation (as I'm rather
> inexperienced).
>
> Philipp
>

I think the reasoning is just that in _general_, free functions are more
_generic_ than member functions, making your generic code, more, well,
_generic_. :-)

ie if you run into a case where you want to run your generic code on
types that do not have the required member functions, you might still be
able to run your code using free functions.

Concrete example:  Windows HWND do not have 'next()' functions, you need
to use GetNextWindow().  So my code that iterates over
 "things that have next() member functions"
can't iterate over HWNDs, but my code that iterates over
 "things that work with free function: next(thing)"
can, if I just write
HWND next(HWND hwnd)
{
    return GetNextWindow(hwnd);
}

So
 "things that work with free function: next(thing)"
is more generic than
 "things that have next() member functions"

Particularly considering:

template <typename T>
T next(T t)
{
    return t.next();
}

can be written to cover all the already-have-a-member-function cases.

Tony

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]