0

我在实现使用 of 时遇到了麻烦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);
4

2 回答 2

1

我真的很喜欢 dauphic 的回答——应该可以。

如果你确实有一个符合 C++11(-ish;) 的编译器,你可以去掉struct,并简单地用这个替换for循环:

std::for_each(
    cleaned.begin(), 
    cleaned.end(), 
    [](char &c) { c = tolower(c); });

PS既然你要求解释:最后一个参数for_each()是一个lambda表达式。将为字符串中的每个字符调用一次 lambda 函数。进一步分解:

  • []:这里的空集意味着clean_entry()在 lambda 内部无法访问任何 ' 变量(如果您想cleaned在 lambda 函数内部引用,则可以使用[&cleaned])。
  • (char &c)(或(string::value_type& c)):定义如何将迭代参数(字符串的单个字符)传递给 lambda 函数(通过引用,因为我们需要修改它)。
  • {c = tolower(c);}: lambda 函数的主体,不言自明。

PPS 为了完整起见:我假设这只是为了玩 for_each,而不是用于实际的生产代码,因为tolower()这里使用的 不处理语言环境,其他方法可以更简洁/清晰,例如作为

  for (char &c : cleaned) {
        c = tolower(c);
  }

或者

std::transform(cleaned.begin(), cleaned.end(), cleaned.begin(), tolower);

.

于 2013-09-26T17:16:55.153 回答
1

std::for_each将仿函数应用于给定范围内的每个元素。它将实际元素传递给您的仿函数 ( *it),而不是迭代器本身。

在您的情况下,void operator()(string::iterator strIter)应更改为void operator()(string::value_type& character)

于 2013-09-26T00:46:06.880 回答