我遇到了下面的代码,但需要一些帮助来理解代码。假设字符串s的两边都有空格。
string trim(string const& s){
auto front = find_if_not(begin(s), end(s), isspace);
auto back = find_if_not(rbegin(s), rend(s), isspace);
return string { front, back.base() };
}
作者说,后面指向最后一个空格的末尾,而前面指向第一个非空白字符。所以 back.base()被调用了,但我不明白为什么。
在return语句中跟随字符串后,花括号是什么?
答案 0 :(得分:28)
大括号是新的C ++ 11初始化。
.base()
并反转迭代器
.base()
是返回底层迭代器(back
是reverse_iterator
),以便从有效范围正确构造新字符串。
一张照片。字符串的正常迭代器位置(关于rend()
如何工作,它比这更复杂一点,但概念上无论如何......)
begin end
v v
-------------------------------------
| sp | sp | A | B | C | D | sp | sp |
-------------------------------------
^ ^
rend rbegin
一旦你的两个find循环完成,这个序列中的迭代器的结果将定位在:
front
v
-------------------------------------
| sp | sp | A | B | C | D | sp | sp |
-------------------------------------
^
back
我们是否只接受那些迭代器并从它们构造一个序列(我们不能,因为它们不匹配类型,但无论如何,我们都可以),结果将是“从A开始复制,停止在D“但在结果数据中不包括D 。
输入反向迭代器的back()
成员。它返回一个前向迭代器类的非反向迭代器,它位于后迭代器“旁边”的元素上;即。
front
v
-------------------------------------
| sp | sp | A | B | C | D | sp | sp |
-------------------------------------
^
back.base()
现在当我们复制我们的范围{ front, back.base() }
时,我们从A
开始复制并停在第一个空格(但不包括它),从而包括我们将拥有的D错过。
它实际上是一段光滑的小代码,顺便说一句。
进行一些额外检查
在原始代码中添加了一些基本检查。
在努力保持原始代码的精神(C ++ 1y / C ++ 14用法)时,只为空白和空格添加一些基本检查字符串;
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 back = find_if_not(rbegin(s), make_reverse_iterator(front), is_space);
return string { front, back.base() };
}