Boost logo

Boost Users :

From: Pavol Droba (droba_at_[hidden])
Date: 2005-12-13 14:44:11


On Tue, Dec 13, 2005 at 01:00:05PM -0600, Thore Karlsen wrote:
> On Tue, 13 Dec 2005 19:24:49 +0100, Pavol Droba <droba_at_[hidden]>
> wrote:
>
> >> split() is declared as follows:
> >>
> >> template<typename SequenceSequenceT, typename RangeT, typename
> >> PredicateT> SequenceSequenceT &
> >> split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred,
> >> token_compress_mode_type eCompress = token_compress_off);
> >>
> >> Is there a reason why Input isn't const? It would be nice to be able to
> >> construct an iterator range in the call to split(), like this:
> >>
> >> typedef iterator_range<string::const_iterator> range;
> >> vector<range> inputs;
> >> split(inputs, range(Begin, End), is_any_of("\r\n"), token_compress_on);
> >>
> >> It's the same for find_all(), ifind_all(), and probably others, so there
> >> might be a good reason for it that I'm missing.
>
> >The const is not missing there. Because the function is templated,
> >const is added to the calculated type.
> >
> >Example:
> >
> >std::string str("Hello world");
> >const std::string cstr("Good bye world");
> >
> >
> >split(res, str, pred); // RangeT is substituted to std::string
> >split(res, cstr, pred); // RangeT is substituted to const std::string
> >
> >
> >So you can use the code you have described without problems.
>
> Hmm.. I can use a const value just fine, but I can't use a temporary. At
> least not in VC++ 8.0 with the warning level set to 4 (I compile all my
> code at warning level 4). I get a warning C4239:
>
> warning C4239: nonstandard extension used : 'argument' : conversion from
> 'boost::iterator_range<IteratorT>' to 'range &'
> with
> [
>
> IteratorT=std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char>>
> ]
> A non-const reference may only be bound to an lvalue
>

I see your problem now. The restriction of temporaries is important in find algorithms.
Since they return 'a reference' (in the form of iterator_range) into the input,
passing a temporary there is dangerous.

split can be used this way too:

vector<iterator_range<string::iterator> > result;
string str("hello world");

split(result, str, is_space);

I see no universal solution here until r-value reference will be added to the language.
Until then I prefer the 'safer' one (given the fact, that it is not very restrictive and
can be easily workarounded)

Regards,
Pavol


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net