Standart Kitaplık kapsayıcılarının yarı açık aralıklarda [begin, end)
olduğunu fark etmek çok önemlidir, yani, bir uçtan uca yineleyebilirsiniz. İki yönlü (ve rastgele) yineleyiciler için --end()
da yapabilir ve eşikten geri dönebilirsiniz. *end()
tarafından bir sonrakinin sonlandırılması tanımlanmamış bir davranıştır ve bu nedenle --begin()
veya begin() - 1
tarafından başlatıcı yineleyici azaltılır. Buna tek bir istisna vardır: std::forward_list
(before_begin()
),10 (forward_list
için begin()
değerini azaltamayacağınızı unutmayın).
İki yönlü yineleyiciler için bu temel asimetri, ters yineleyicilerin normal yineleyiciler etrafında ince sarmalayıcılar olduğu anlamına gelir. Çoğu Standart Kitaplık uygulamasında, basitçe alt yineleme yineleyicisinin bir kopyasını base_
içerir. std::reverse_iterator
değerini artırma, --base_; return *this;
ve kayıttan kaldırmayı auto old = base_; return *--old;
yapar. Hiçbir noktada, altta yatan yineleyici begin()
'dan önce azaltılmış ve end()
'un yok sayılması bu şekilde yapılmamıştır.Aşağıda
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
int main()
{
auto c = std::map<int, std::string>{ {1, "hello"}, {2, "world"} };
{ // 1) forward iteratation
auto it = begin(c);
for (; it != end(c); ++it){}
std::cout << std::boolalpha << (it == c.rbegin().base()) << "\n";
}
{ // 2) meh, backward iteration
auto it = end(c);
for (; it != begin(c); --it){}
std::cout << std::boolalpha << (it == c.rend().base()) << "\n";
}
{ // 2') better: reverse iteration
auto it = c.rbegin();
for (; it != c.rend(); ++it){}
std::cout << std::boolalpha << (it.base() == begin(c)) << "\n";
}
{ // 1') backward reverse, better avoid this
auto it = c.rend();
for (; it != c.rbegin(); --it){}
std::cout << std::boolalpha << (it.base() == end(c)) << "\n";
}
}
Live Example
(.base()
altta yatan yineleyici bir geri std::reverse_iterator
dönüştürür) çift yönlü ya da rastgele bir yineleyici destekleyen bir kap yineleme dört yolu ve çeşitli yineleyicileri arasındaki ilişkiler İki yönlü yinelemeyi desteklemesi gereken veri yapısına sahipseniz ancak .rbegin()
veya rend()
numaralı üye yineleyicileri yoksa, bunları std::reverse_iterator(end())
vearacılığıyla kolayca tanımlayabilirsiniz. Sırasıyla 10 (Standart Kitaplığın genellikle bunları uyguladığı yol).
Kısa yanıt: Hayır. Durumu gerçekten ele almanın başka bir yolunu bulmanız gerekiyor (ya da daha iyisi, önleyin). –
@JerryCoffin bu yüzden ters yineleyicilerimiz var, cevabımı gör – TemplateRex