Şu anda bu kadar kod ve çalışan var: Ben istiyorumsadece bir kez
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
daha kompakt ve bunu okunabilir hale getirmek için:
- mevcut standart C Oluşturma ++ sadece bir kez döngü gerçekleştirin
- algoritmaları (*)
(*) o c farz ediyorum jrok tarafından önerildiği gibi, özel bir transform_until
algoritma tanımlamanın yanı sıra
... Alternatif çözüm
mevcut algoritmaları kodum daha okunabilir hale ombining, kullanarak yineleme olurdu özel bir yineleyici adaptörü tanımlamak mümkün olabilir temel yineleyici, ancak geri döndürmeden önce temel referansı değiştirerek operatörü *() yeniden tanımlar. Böyle şey: bu hala çok ham, ancak fikir vermelidir
template <typename Iterator, typename UnaryFunction = typename Iterator::value_type (*)(typename Iterator::value_type)>
class sidefx_iterator: public std::iterator<
typename std::forward_iterator_tag,
typename std::iterator_traits<Iterator>::value_type,
typename std::iterator_traits<Iterator>::difference_type,
typename std::iterator_traits<Iterator>::pointer,
typename std::iterator_traits<Iterator>::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<Iterator>& other) const { return current_ == other.current_; }
bool operator==(const Iterator& other) const { return current_ == other; }
bool operator!=(const sidefx_iterator<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_;
};
Elbette. Yukarıdaki adaptör ile , ben sonra aşağıdaki yazabilirsiniz: ile
word.erase(std::find_if(it, it_end, std::not1(std::ref(::isalpha))), word.end());
(bazı şablon sihirli basitleşeceğini olabilir) önceden tanımlanmış aşağıdaki: Standart içerecektir
using TransformIterator = sidefx_iterator<typename std::string::iterator>;
TransformIterator it(word.begin(), reinterpret_cast<typename std::string::value_type(*)(typename std::string::value_type)>(static_cast<int(*)(int)>(std::toupper)));
TransformIterator it_end(word.end(), nullptr);
ise Böyle bir adaptör kullanacağım, çünkü bunun kusursuz olduğu anlamına geliyordu, ama bu durum böyle olmadığından belki de döngümüzü olduğu gibi tutacağım. bir adaptör algoritmaları mevcut ve mümkün değil bugün farklı şekillerde karıştırma yeniden sağlayacak, ama daha iyi anlaşılması sonra ... Ben muhtemelen şu anda bakan ediyorum ki, hem
Geçerli kodumda tek bir döngü var. Benim amacım, yeniden yazmanın ardından hala tek bir döngü olacaktı. –
'! Isalpha (* it)' esasına dayanan prematüre çıkış, potansiyel olarak sizi aradığınızı düşündüğüm şeyi elde etmekten alıkoyduğumu gördüğüm tek şey ve dürüstçe, sizin için yapabileceğiniz her şeyi (ve ben hemen hemen her şeyi görürsünüz) büyük ihtimalle bu kadar kıvılcımlı olacaksınız, açıklık faktörü pencereden dışarı çıkacaksınız. Muhtemelen sahip olduklarına bağlı kalırım. – WhozCraig
İlham veren cevaplarınız için hepinize teşekkür ederim. Şu anki kodumla sadık kalacağım. Boost :: transform_iterator'ın aradığım en yakın şey olduğuna inanıyorum. Bu kullanım durumu, "yan etkiler" yineleyici bağdaştırıcısı tarafından, bu şekilde kullanılacak bir şeyle ele alınacaktır: word.erase (std :: find_if (sidefx_iterator (word.begin(), :: toupper), word.end (), std :: not1 (:: isalpha)), word.end()); –