Boost logo

Boost :

From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2005-05-12 03:37:57


"Thorsten Ottosen" <nesotto_at_[hidden]> writes:

> "Anthony Williams" <anthony_w.geo_at_[hidden]> wrote in message
> news:fywten01.fsf_at_yahoo.com...
> | "Thorsten Ottosen" <nesotto_at_[hidden]> writes:
> |
> | > "Anthony Williams" <anthony_w.geo_at_[hidden]> wrote in message
> | > news:k6m6f12b.fsf_at_yahoo.com...
> | > | "Thorsten Ottosen" <nesotto_at_[hidden]> writes:
> | > |
> | > | > "Peter Dimov" <pdimov_at_[hidden]> 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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk