[string_algo] split input parameter not const?

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. -- Be seeing you.

On Tue, Dec 13, 2005 at 11:01:25AM -0600, Thore Karlsen 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. Regards, Pavol.

On Tue, 13 Dec 2005 19:24:49 +0100, Pavol Droba <droba@topmail.sk> 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 -- Be seeing you.

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@topmail.sk> 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

On Tue, 13 Dec 2005 20:44:11 +0100, Pavol Droba <droba@topmail.sk> wrote: [...]
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)
Thanks, that makes sense. I don't mind working around it if this is by design, I just wanted to make sure. It's a very minor inconvenience anyway. Thanks for the great work! -- Be seeing you.
participants (2)
-
Pavol Droba
-
Thore Karlsen