2010-02-15 12 views
7

Her bir öğe çiftinde çalışmak için std :: listesinin üzerinde bir çift döngü yapmaya çalışıyorum. Ancak, ikinci yineleyici başlatırken bazı sorun yaşıyorum. Ben yazmak istiyorum koddur:Bir std :: liste yineleyicisi döngüde artışla nasıl oluşturulur

liste yineleyiciler rasgele erişimli değildir çünkü çalışmaz, bu nedenle +1 yapamaz
for(std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    for(std::list<int>::iterator j = i+1; j != l.end(); ++j) { 
     ... 
    } 
} 

. Ama ben düzgün bir alternatif bulmada bazı sorun yaşıyorum; Derleyici, umudum olan std::list<int>::iterator j(i)++; ile çok mutlu görünmüyor. İstediğimi elde etmek, for döngüsünün yapısına uygun olmayan bazı garip ekstra artışlara sahip olmak gibi görünecek gibi görünüyor.

Apaçık alternatifler vardır (örneğin, bir vektör kullanarak!) Ama bana öyle görülemediğim bazı makul şekilde düzgün bir şekilde yapılmalıdır. Herhangi bir yardım için şimdiden

Teşekkür :) Geri oyunda

cevap

7

Özet olun:

// for consistency, 
template <typename Iter> 
void increment(Iter& pIter) 
{ 
    ++pIter; 
} 

template <typename Iter> 
Iter increment_copy(Iter pIter) 
{ 
    return ++pIter; 
} 

// ... 

typedef std::list<int> int_list; 

for(int_list::iterator i = l.begin(); i != l.end(); ++i) 
{ 
    for(int_list::iterator j = increment_copy(i); j != l.end(); ++j) 
    { 
    } 
} 
4
for(std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    std::list<int>::iterator j = i; ++j; 
    for(; j != l.end(); ++j) { 
     ... 
    } 
} 

! Aslında bu, sayısal algoritmalarda oldukça sık kullanılan bir deyimdir, bu yüzden onu çirkin olarak görmüyorum. Sadece fikir çıkıyorum

for (std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    for (std::list<int>::iterator j = i; ++j != l.end();) { 
     // ... 
    } 
} 
9
for(std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    std::list<int>::iterator j = i; 
    for(std::advance(j, 1); j != l.end(); ++j) { 
     ... 
    } 
} 
+0

'advance' hiçbir dönüş değeri yoktur, ilk bağımsız değişkeni değiştirir. (Ben şahsen hoşlanmıyorum.) Bu, bir 'advance_copy' işlevi yazmak kolay. – GManNickG

+0

@GMan: Sabit. Ty! – dirkgently

+0

Sorun değil. Benim fikrim ile alternatif bir cevap olarak gitmeye karar verdim. – GManNickG

2

Ben dirkgently cevabını vardı: Sen de yarar fonksiyonların başka sınıfını yapabilirsiniz

template <typename Iter, typename Dist> 
Iter advance_copy(Iter pIter, const Dist& pOffset) 
{ 
    std::advance(pIter, pOffset); 

    return pIter; 
} 

// ... 

typedef std::list<int> int_list; 

for(int_list::iterator i = l.begin(); i != l.end(); ++i) 
{ 
    for(int_list::iterator j = advance_copy(i, 1); j != l.end(); ++j) 
    { 
    } 
} 

, yardım etmek konusunda nasıl

1

for (std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    std::list<int>::iterator j(i); 
    while(++j != l.end()) { 
     // ... 
    } 
} 
0

Zaten Boost kullanıyorsanız, o zaman kolay yaklaşım boost::next kullanmaktır: r Sean'ın öneri dışında bir süre döngü yapmak.

for(std::list<int>::iterator i = l.begin(); i != l.end(); ++i) 
    for(std::list<int>::iterator j = boost::next(i); j != l.end(); ++j) 
+0

Yani Boost benim fikrimi çaldı. :( – GManNickG

2

basit "temiz" bir alternatif (dahili bir tipine karşı) listesi yineleyici aşırı operatörleri ile kullanıcı tanımlı tür bir amacı olduğu gerçeğine dayalı olabilir. (Tabi ki, bu resmi olarak garanti edilmez, ancak bu liste konteynerinin doğasına dayanarak beklenebilir.) Bu nedenle, aşırı yüklenmiş önek ++ operatörünü geçici bir liste yineleyici nesnesine uygulamak mümkündür.

sadece, i geçici bir kopyasını oluşturmak öneki ++ kullanarak artırmak ve daha sonra j

for(std::list<int>::iterator i = l.begin(); i != l.end(); ++i) { 
    for(std::list<int>::iterator j = ++std::list<int>::iterator(i); j != l.end(); ++j) { 
    ... 
    } 
} 

başlatmak için çıkan değeri kullanmak için gerekenleri istediğiniz ulaşmak için Ve işte bu kadar. Not, bu hile oldukça popüler ve zaman zaman gerçek kodla karşılaşılabilir. Ayrıca, çoğu uygulama normal yinelenen imleçler olarak kullanıldığından, genellikle std::vector ile çalışmaz, ancak normal olarak std::list ile çalışır. Bununla birlikte, kişisel olarak, bunu gerçekten benim kodumda kullanamazdım.Fazladan bir kod satırı ekleyerek bunu yapmak için çok sayıda iyi yanıt aldınız.

İlgili konular