2010-06-01 14 views
6

Bir yineleyicinin işaret ettiği deque öğesinin dizinini döndürmem ve döndürmem gerekiyor. Bir yineleyiciden nasıl ayrılırım?C++'da, bir yineleyicinin int dizinini nasıl alabilirim?

+0

Dizine neden ihtiyaç duyuyorsunuz? Sadece nesneyi geçersiz kılabilir ve üzerinde yineleyici aritmetik yapamaz mısınız? –

+0

Ne kadar? Yineleyiciden vazgeçme, bir işaretçiyi iptal etmek ve bana bellek adresini vermek, deque'deki yeri değil midir? – user83

cevap

3
std::ptrdiff_t index = std::distance(myDeque.begin(), curIterator); 
9

Sen kullanabilirsiniz:

std::ptrdiff_t index(std::distance(my_container.begin(), my_iterator)); 

böyle bir rutin çalışma zamanı maliyetlerinin farkında olun, bunu kullandığınız veri yapısına bağlıdır Ancak-.

size_t index = some_iterator - some_deque.begin() 

Açıkçası bu (. std::list ya da her türlü örneğin) tüm yineleyiciler için çalışmaz ama belli bir zerafet içinde var olduğunu teslim ediyorum:

+1

Veya daha doğrusu yineleyici sınıfına bağlıdır (rastgele, ileri, vb) –

+0

Numarayı bulmak için konteynerin her bir öğesi aracılığıyla mesafe adımları varsayalım, bu yüzden büyük bir deque için çalışma zamanı maliyeti büyük olacaktır. Bununla birlikte, benim dequeum 10 elementten daha büyük olmamalıdır. Ve mesafe bir int? Index() çağrısı ne yapar? – user83

+0

Eğer deque'nizde 10'dan fazla elementin olmaması gerekiyorsa, o zaman 'vektör' kullanmanız gerektiğini veya en azından deque ile yapışmak için iyi bir mantığa sahip olmanızı rica ediyorum. Index() "call", "std :: distance" öğesinden dönüş değeriyle oluşturulmuş olan "index" adlı bir değişkendir. – fbrereto

4

rasgele erişimli adım adım elde için sadece çıkarma kullanabilirsiniz Bu tekniği yalnızca sabit zaman alacağı zaman kullanabileceğinizi. Konteyneriniz rasgele erişim yineleyicileri içermiyorsa, büyük olasılıkla yine de bunların indeksini bulmaya çalışmak mantıklı değildir. İki sunulan yöntemlerin dışında

+0

Bence bu basitliği ve zarafeti için en iyi cevabı vereceğim. Sonucu bir int'ye atamak için bir int olarak atayabilir miyim? – user83

+0

Bir int için atayabilirsiniz, ancak büyük olasılıkla daha yüksek uyarı düzeylerinde bir derleyici uyarısı alırsınız (ya imzalanmamış dönüşüm ya da derleyiciye bağlı olarak türün gerçek kısaltması vb.).Açıkça int için cast yapmak biraz can sıkıcı, ama bu senin deque içinde 2 milyardan fazla elemente sahip olmadıkça bir problemi gizlemeyecek - ki sanırım olmayacağından emin olabilirsin. – Peter

2

: İkinci rasgele erişim yineleyiciler için geçerlidir olmanın bir üstünlüğe sahiptir

std::ptrdiff_t index(std::distance(my_container.begin(), my_iterator)); 

ve

std::ptrdiff_t index = some_iterator - some_deque.begin() 

... - Başka kap için değiştirirken dolayısıyla Yanlışlıkla pahalı bir işlem yapmazsınız (örneğin listeler için O (n)).

İlgili konular