我在实现for_each
的使用时遇到了麻烦,我可以通过for循环完成工作,但为了理解,我可以使用一些帮助解释...我有到目前为止的以下功能...
void clean_entry(const string& orig, string& cleaned) {
size_t start = 0;
size_t end = 0;
while(!isalnum(orig[start]) && start < orig.length())
start++;
end = start;
while(isalnum(orig[end]) && end < orig.length())
end++;
cleaned = orig.substr(start,(end-start));
// I want to replace the following lines with a for_each loop
string::iterator iter;
for(iter = cleaned.begin(); iter != cleaned.end(); iter++)
*iter = tolower(*iter);
}
在我尝试在上面的函数中为最后三行代码实现for_each循环时,我尝试了下面的代码,这给了我一个编译错误......
struct {
void operator()(string::iterator strIter) {
*strIter = tolower(*strIter);
}
} lower;
for_each(cleaned.begin(),cleaned.end(),lower);
答案 0 :(得分:1)
std::for_each
将一个仿函数应用于给定范围内的每个元素。它将实际元素传递给您的仿函数(*it
),而不是迭代器本身。
在您的情况下,void operator()(string::iterator strIter)
应更改为void operator()(string::value_type& character)
答案 1 :(得分:1)
我真的很喜欢dauphic的答案 - 这应该可行。
如果你有一个符合C ++ 11的(-ish;)编译器,你可以摆脱struct
,只需用这个替换for
循环:
std::for_each(
cleaned.begin(),
cleaned.end(),
[](char &c) { c = tolower(c); });
PS因为您要求解释:for_each()
的最后一个参数是lambda表达式。 lambda函数将为字符串中的每个字符调用一次。进一步分解:
[]
:这里的空集意味着lambda内部都不能访问clean_entry()
个变量(如果你想在lambda函数中引用cleaned
,你会改为使用[&cleaned]
)。 (char &c)
(或(string::value_type& c)
):定义如何将迭代参数(字符串的各个字符)传递给lambda函数(通过引用,因为我们需要修改它)。 / LI>
{c = tolower(c);}
:lambda函数的主体,不言自明。 PPS为了完整起见:我假设这只是为了使用for_each,而不是用于实际的生产代码,因为这里使用的tolower()
不处理语言环境和其他方法可以更简洁/清晰,例如
for (char &c : cleaned) {
c = tolower(c);
}
或
std::transform(cleaned.begin(), cleaned.end(), cleaned.begin(), tolower);