2009-03-22 33 views
162

Vì vậy, tôi đã viết một loạt các mã truy cập các phần tử trong một vector stl bằng chỉ mục [], nhưng bây giờ tôi cần phải sao chép chỉ là một đoạn của vectơ. Có vẻ như vector.insert(pos, first, last) là chức năng tôi muốn ... ngoại trừ tôi chỉ có đầu tiên và cuối cùng là ints. Có cách nào tốt đẹp tôi có thể có được một iterator cho các giá trị này?C++ STL Vectors: Nhận trình lặp từ chỉ mục?

+1

Xem thêm: http://stackoverflow.com/q/2152986/365102 –

Trả lời

234

Hãy thử điều này:

vector<Type>::iterator nth = v.begin() + index; 
+4

Nói chung, bạn có thể sử dụng số học tương tự với vòng lặp STL hơn với con trỏ. Chúng được thiết kế để có thể trao đổi khi sử dụng các thuật toán STL. –

+14

@VincentRobert: Cách khác. Con trỏ là việc triển khai hợp lệ các trình lặp ngẫu nhiên STL, danh mục mạnh nhất. Nhưng các loại khác, ít mạnh mẽ hơn như các trình vòng lặp chuyển tiếp không hỗ trợ cùng một số học. – MSalters

+0

Tôi muốn ot thêm năm xu của tôi vào câu trả lời này và đề nghị 'std :: next (v.begin(), index)' – stryku

75

cách đề cập bởi @dirkgently (v.begin() + index) thoải mái và nhanh chóng cho vectơ

nhưng std::advance(v.begin(), index) cách chung chung nhất và cho lặp truy cập ngẫu nhiên làm việc hằng số thời gian quá.

EDIT
khác biệt trong sử dụng:

std::vector<>::iterator it = (v.begin() + index); 

hoặc

std::vector<>::iterator it = v.begin(); 
std::advance(it, index); 

thêm vào sau khi ghi chú @litb.

+0

không std :: trước yêu cầu một biến lặp không phải là đối số đầu tiên? – goldPseudo

+0

theo cách này - http://www.sgi.com/tech/stl/advance.html - không. – bayda

+0

bạn có thể sử dụng lệnh std :: advance với các trình biến đổi const và không lặp const – bayda

-3

Actdally std :: vector được dùng để làm tab C khi cần. (C++ yêu cầu tiêu chuẩn để thực hiện vector, như xa như tôi biết - replacement for array in Wikipedia) Ví dụ đó là hoàn toàn hợp pháp để làm folowing này, theo tôi:

int main() 
{ 

void foo(const char *); 

sdt::vector<char> vec; 
vec.push_back('h'); 
vec.push_back('e'); 
vec.push_back('l'); 
vec.push_back('l'); 
vec.push_back('o'); 
vec.push_back('/0'); 

foo(&vec[0]); 
} 

Tất nhiên, một trong hai foo không phải sao chép địa chỉ thông qua như một tham số và lưu trữ nó ở đâu đó, hoặc bạn nên đảm bảo trong chương trình của bạn để không bao giờ đẩy bất kỳ mục mới nào trong vec, hoặc yêu cầu thay đổi dung lượng của nó. Hoặc lỗi segmentation nguy cơ ...

Do đó trong dụ của bạn nó dẫn đến

vector.insert(pos, &vec[first_index], &vec[last_index]); 
+0

Làm cho tôi băn khoăn tại sao họ quyết định trừu tượng hóa các trình vòng lặp nếu chúng chỉ là con trỏ ... về cơ bản chúng "ẩn" những khả năng này. – mpen

+0

Vì sự đồng thuận? Vì nó sẽ cho phép bạn dễ dàng loại bỏ cá thể vector cho bất kỳ loại container nào khác trong mã của bạn như vậy. –

+4

& vec [i] tạo ra một con trỏ không nhất thiết phải tương thích với vectơ <> :: iterator. vec.begin() + i vẫn có lợi ích của việc lặp lại bất kỳ thứ gì mà thư viện của bạn định nghĩa nó - bao gồm các trình vòng lặp được kiểm tra trong chế độ gỡ lỗi, ví dụ. Vì vậy, nếu bạn không cần một con trỏ (cho I/O chẳng hạn), bạn nên luôn luôn thích các trình vòng lặp. – sellibitze

7

Hoặc bạn có thể sử dụng std::advance

vector<int>::iterator i = L.begin(); 
advance(i, 2); 
33

Cũng; auto it = std::next(v.begin(), index);

Cập nhật: Nhu cầu một C++ 11x biên dịch phù

+2

Cần lưu ý rằng đây là cách C++ 11! std :: next tương đương với std :: advance. Sử dụng các chức năng này thay vì sử dụng arithmetics làm cho việc trao đổi các loại container dễ dàng hơn rất nhiều. Thậm chí làm việc trên c-mảng afaik, giống như std :: begin và std :: end. – Zoomulator

+2

Cũng cần lưu ý rằng std :: advance được thiết kế bởi một kẻ ngốc vì nó sử dụng tham chiếu làm đầu ra chứ không phải giá trị trả về. –

+1

cho (auto it = begin (c); it! = End (c); trước (nó, n)) {...} – Zoomulator

Các vấn đề liên quan