Объединение стандартных алгоритмов C ++ с помощью цикла только один раз

В настоящее время у меня есть этот код и работает:

string word="test,";
string::iterator it = word.begin();
for (; it != word.end(); it++)
{
    if (!isalpha(*it)) {
        break;
    }
    else {
       *it = toupper(*it);
    }
}
word.erase(it, word.end());
// word should now be: TEST

Я хотел бы сделать его более компактным и читаемым:

Составление существующих стандартных алгоритмов C ++ (*)Выполните цикл только один раз

(*) ЯЯ предполагаю, что объединение существующих алгоритмов делает мой код более читабельным ...

Альтернативное решение

В дополнение к определению обычаяtransform_until По алгоритму, предложенному jrok, можно определить пользовательский адаптер итератора, который будет выполнять итерацию, используя базовый итератор, но переопределять оператор * (), изменяя базовую ссылку перед ее возвратом. Что-то вроде того:

template 
class sidefx_iterator: public std::iterator<                          typename std::forward_iterator_tag,
                         typename std::iterator_traits::value_type,
                         typename std::iterator_traits::difference_type,
                         typename std::iterator_traits::pointer,
                         typename std::iterator_traits::reference >
{
  public:
    explicit sidefx_iterator(Iterator x, UnaryFunction fx) : current_(x), fx_(fx) {}

    typename Iterator::reference operator*() const { *current_ = fx_(*current_); return *current_; }
    typename Iterator::pointer operator->() const { return current_.operator->(); }
    Iterator& operator++() { return ++current_; }
    Iterator& operator++(int) { return current_++; }
    bool operator==(const sidefx_iterator& other) const { return current_ == other.current_; }
    bool operator==(const Iterator& other) const { return current_ == other; }
    bool operator!=(const sidefx_iterator& other) const { return current_ != other.current_; }
    bool operator!=(const Iterator& other) const { return current_ != other; }
    operator Iterator() const { return current_; }

  private:
    Iterator current_;
    UnaryFunction fx_;
};

Конечно, это все еще очень сырой, но это должно дать идею. С помощью вышеуказанного адаптера я мог бы написать следующее:

word.erase(std::find_if(it, it_end, std::not1(std::ref(::isalpha))), word.end());

со следующим определенным заранее (что может быть упрощено с помощью некоторой магии шаблона):

using TransformIterator = sidefx_iterator;
TransformIterator it(word.begin(), reinterpret_cast(static_cast(std::toupper)));
TransformIterator it_end(word.end(), nullptr);

Если бы стандарт включал в себя такой адаптер, я бы использовал его, потому что это означало бы, что он был безупречным, но так как это не тот случай, яЯ, вероятно, буду держать мою петлю как есть.

Такой адаптер позволил бы повторно использовать существующие алгоритмы и смешивать их различными способами, что сегодня невозможно, но у него могут быть и недостатки, которые ям скорее всего с видом на данный момент ...

Ответы на вопрос(2)

Ваш ответ на вопрос