Boost's find_first
algorithm is a souped-up equivalent of C's strstr()
, but why does the haystack — the search space — get passed in as a non-const reference? The matching range is returned in a separate iterator_range
object, so it's not a matter of output-by-reference.
It prevents invocation with a temporary range created by make_iterator_range.
const std::string str("haystack");
const std::string findstr("stack");
boost::sub_range<const std::string> match = boost::algorithm::find_first(
boost::make_iterator_range(str),
boost::make_iterator_range(findstr));
Instead, a local variable representing the source range must be created explicitly:
const std::string str("haystack");
const std::string findstr("stack");
boost::sub_range<const std::string> haystack = boost::make_iterator_range(str);
boost::sub_range<const std::string> match = boost::algorithm::find_first(
haystack,
boost::make_iterator_range(findstr));
(This applies equally to the other functions in boost/algorithm/string/find.hpp, ie. find
, ifind_first
, find_last
, ifind_last
, find_nth
, ifind_nth
, find_head
, find_tail
& find_token
).
It's to ensure that the returned range is still valid after the call to find_first
.
While the initial case above would be fine, the following would result in a match
that points to a destroyed temporary string:
boost::sub_range<const std::string> match = boost::algorithm::find_first(
boost::make_iterator_range(std::string("haystack"),
boost::make_iterator_range(std::string("stack"));
The requirement that the haystack be non-const prevents it binding to a temporary object (rvalue) which is destroyed upon find_first
's return and invalidates the match
's iterators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With