c++ - Explaining a string trimming function -
i came across code below need understanding code. assume string s has spaces either side.
string trim(string const& s){ auto front = find_if_not(begin(s), end(s), isspace); auto = find_if_not(rbegin(s), rend(s), isspace); return string { front, back.base() }; }
the author stated points end of last space whereas front points first non-white space character. back.base() called don't understand why.
also curly braces, following string in return statement, represent?
the braces new c++11 initialisation.
.base()
, reverse iterators
the .base()
the underlying iterator (back
reverse_iterator
), construct new string valid range.
a picture. normal iterator positions of string (it little more complex regarding how rend()
works, conceptually anyway...)
begin end v v ------------------------------------- | sp | sp | | b | c | d | sp | sp | ------------------------------------- ^ ^ rend rbegin
once 2 find loops finish, result of iterators in sequence positioned at:
front v ------------------------------------- | sp | sp | | b | c | d | sp | sp | ------------------------------------- ^
were take iterators , construct sequence them (which can't, they're not matching types, regardless, supposed could), result "copy starting @ a, stopping @ d" but not include d in resulting data.
enter back()
member of reverse iterator. returns non-reverse iterator of forward iterator class, positioned @ element "next to" iterator; i.e.
front v ------------------------------------- | sp | sp | | b | c | d | sp | sp | ------------------------------------- ^ back.base()
now when copy our range { front, back.base() }
copy starting @ a
, stopping @ first space (but not including it), thereby including d have missed.
its slick little piece of code, btw.
some additional checking
added basic checks original code.
in trying keeping spirit of original code (c++1y/c++14 usage), adding basic checks empty , white space strings;
string trim_check(string const& s) { auto is_space = [](char c) { return isspace(c, locale()); }; auto front = find_if_not(begin(s), end(s), is_space); auto = find_if_not(rbegin(s), make_reverse_iterator(front), is_space); return string { front, back.base() }; }
Comments
Post a Comment