
"Thorsten Ottosen" <nesotto@cs.auc.dk> writes:
"Anthony Williams" <anthony_w.geo@yahoo.com> wrote in message news:fywten01.fsf@yahoo.com... | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | | > "Anthony Williams" <anthony_w.geo@yahoo.com> wrote in message | > news:k6m6f12b.fsf@yahoo.com... | > | "Thorsten Ottosen" <nesotto@cs.auc.dk> writes: | > | | > | > "Peter Dimov" <pdimov@mmltd.net> wrote in message | > | > | > and it also makes it harder to treat const char[N] differently. | > | | > | That's covered by Peter's suggestion. | > | > it would need a special sentence saying if T is char, the range is [array, | > array+N-1]. | | So, you would *enforce* that char arrays were treated as null-terminated | strings? Ouch. No thanks. If I want a char array treated as a string, I'll | cast it to a std::string, or pass it through make_range.
well' that the behavior currently. The string algorithms rely on this behavior.
Which string algorithms exactly? The functions in the standard that deal with null-terminated strings all deal with char * and const char *, rather than arrays.
| That would create a special case like std::vector<bool>. I might use an array | of chars just as an array of small integers, and iterating through it should | therefore go all the way to the end, not one before. Besides, if I think it's | a null-terminated string, I don't want all-but-the-last-byte-in-the-array, I | want up-to-the-null-terminator, which may be in the middle of the array.
char[] might be wrongly specified today, const char[] is not.
Huh?
| > the member function idea is not something I have't considered in depth, but it | > does seem non-optimal to me. | > | > consider, for example, the amount of work you need to do to support your own | > types | > if you must rely on member function vs. being able to use free-standing | > functions. | | If the implementation uses free standing functions, you need to write begin() | and end() for your type. If the implementation uses members, you can write | make_range() for your type, *or* write the members.
yep, but the latter approach is harder and takes just about twice as much code in C++0x.
writing an overload for make_range is easy. Writing the members may be harder, especially if you aren't free to change the class, but you have the choice. template<typename T> auto make_range(MyContainer<T> & c) -> decltype(std::make_range(c.Begin(),c.End())) { return std::make_range(c.Begin(),c.End()); } template<typename T> auto make_range(MyContainer<T> const & c) -> decltype(std::make_range(c.Begin(),c.End())) { return std::make_range(c.Begin(),c.End()); } vs template<typename T> auto begin(MyContainer<T> & c) -> decltype(c.Begin()) { return c.Begin(); } template<typename T> auto begin(MyContainer<T> const & c) -> decltype(c.Begin()) { return c.Begin(); } template<typename T> auto end(MyContainer<T> & c) -> decltype(c.End()) { return c.End(); } template<typename T> auto end(MyContainer<T> const & c) -> decltype(c.End()) { return c.End(); } Anthony -- Anthony Williams Software Developer