реализация for_each с tolower

У меня возникли проблемы с реализацией использования 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

Решение

std::for_each применяет функтор к каждый элемент в данном диапазоне. Он передает фактические элементы вашему функтору (*it), а не сам итератор.

В твоем случае, void operator()(string::iterator strIter) следует изменить на void operator()(string::value_type& character)

1

Другие решения

Мне очень нравится ответ Дауфика — это должно сработать.

Если у вас есть компилятор, совместимый с C ++ 11 (-ish;), вы можете избавиться от structи просто замените for цикл с этим:

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

PS Так как вы попросили объяснения: последний параметр for_each() является лямбда-выражением Лямбда-функция будет вызываться один раз для каждого символа в строке. Чтобы разбить его еще дальше:

  • []: пустой набор здесь означает, что ни один из clean_entry()переменные будут доступны внутри лямбды (если вы хотите сослаться cleaned внутри лямбда-функции, вы бы использовали [&cleaned] вместо).
  • (char &c) (или же (string::value_type& c)): определяет, как параметр итерации (отдельные символы строки) будет передаваться в лямбда-функцию (по ссылке, поскольку нам нужно ее изменить).
  • {c = tolower(c);}: тело лямбда-функции, само за себя.

PPS Ради полноты: я предполагаю, что это просто для игры с for_each, а не для реального производственного кода, так как tolower()как используется здесь, не имеет дело с языками, и другие подходы могут быть более краткими / ясными, такими как

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

или же

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

.

1

По вопросам рекламы [email protected]