2017-09-11 63 views
7
işaretçileri rastgele STL yineleyicileri olarak kullanılabilir

I understand (at least I think I do) ile silmek. Ben bir yineleyici işaretçiyi döküm süreceSTL vektör işaretçi

Neden Aşağıdaki kod derleme değil?

vector<int> v{1, 2, 3}; 
v.erase(&v[0]); 
+12

Neden öğeye bir göstericinin yineleyici ile aynı olduğunu düşünüyorsunuz ('std :: vector :: yineleyici ')? – NathanOliver

+1

Hangi hatayı alıyorsunuz? –

+6

Yineleyiciler işaretçiler kullanılarak gerçekleştirilebilirken, bir işaretçi otomatik olarak yineleyici değildir. –

cevap

12

Senstd::sort, std::find veya std::copy gibi algoritmalara işaretçileri geçebilir. Bunlar uygun bir yineleyici olarak çalışan her şey için yapılandırılabilir şablonlardır.

Bu farklı yineleyiciler mutlaka birbirlerine dönüştürmek anlamına gelmez.

std::vector<int> kapsayıcısının erase yöntemiyle yalnızca yineleyicilerle aynı vektörün öğelerine çalışabilir. işaret edildiği gibi, bu işaretçi olarak uygulanan, ama genellikle burada belirtilen nedenlerden dolayı, değil edilebilir: C++ std::vector<>::iterator is not a pointer, why?

std::find düşünün:

İşte InputIt
template< class InputIt, class T > 
InputIt find(InputIt first, InputIt last, const T& value); 

bir şablon parametresidir. std::find şablonu, input iterator gereksinimlerini karşılayan ve operator*, T türüyle karşılaştırılabilecek bir şey döndüren herhangi bir yineleyici türüyle çalışacaktır. İşaretçiler burada iyi çalışıyor. Yangın Lancer yorumunda doğru belirttiği gibi, hem first ve last tip InputIt olmalıdır.

Şimdi std::vector::erase bu karşılaştırmak:

iterator erase(const_iterator pos); 

Bu std::vector sınıfın typedefs biri olan const_iterator, sürer. Bu, belirli bir yineleyici türüdür, şablon parametresi değildir.

+1

İşaretçilerden ** çiftleri ** bu algoritmalara geçmek, rastgele bir erişim yineleyici türüdür. Ancak, bir işaretçi ve vektör yineleyici, işaretçi vektör içinde olsa bile, bunlara "çift" olarak geçemezsiniz. –

1

vector.erase(...) tanımı

iterator erase(const_iterator pos);

const iterator kendi içinde bir sınıf olmasıdır. Yani, bu sınıfa basit bir işaretçinin dönüşümü yapıldıysa, bu yapılabilir. Ama sanırım hiç yok.

Ama bir şey bir yineleyici beklenen bir yerde kullanmaktır, ve başka algoritmalarındaki kullanmaktır. Bir iterator gereklidir

, sadece bir yineleyici kullanılabilir.

Algoritmalarda, bir iterator beklenmez. Sadece bir amacı da bir iterator bir Concept (genellikle begin gerekli yineleyici/işaretçiyi geri end) satisified edilir. işaretçiler yinelemeler rağmen

+0

Algoritmalar yineleyici beklerler, "ne için bir başlangıç ​​/ bitiş ..." nesnesi değil. – juanchopanza

+1

Algoritmalar şablonlar kullanır - parametreler, somut türde '' 'yineleyici''' değildir. Bir '' 'yineleyici'' kavramını tatmin eden herhangi bir nesneyi fonksiyonlara geçirebilirsiniz. –

+0

Benim amacım tam olarak. Düzeltdiğin için teşekkürler. – juanchopanza

0

, aynı tip vektör olarak yinelemeler (en azından olması gerekmez) değildir.

Bir işaretçiyi, vektörün bir elemanına, yineleyici ve işaretçi aritmetiği gibi bir iterere dönüştürebilirsiniz.

std::vector<int> v{1, 2, 3}; 

int* p = &v[0]; // a pointer 

auto v_iter = v.begin() + std::distance(v.data(), p); // an equivalent vector::iterator 

v.erase(v_iter); 

std::vector veya std::array gibi bitişik konteynerleri ile bu sadece çalışır.