2012-01-13 42 views
9

Tôi muốn sử dụng một phương pháp đặc biệt để khởi tạo số std::vector<unsigned int> được mô tả trong sách C++ tôi sử dụng làm tài liệu tham khảo (sách tiếng Đức 'Der C++ Lập trình viên 'của Ulrich Breymann, trong trường hợp có vấn đề). Trong cuốn sách đó là một phần về các loại trình tự của STL, đề cập cụ thể đến list, vectordeque. Trong phần này, ông viết rằng có hai cấu trúc đặc biệt của các loại chuỗi như vậy, cụ thể là, nếu X dùng để chỉ một loại như vậy,Khởi tạo std :: vector <unsigned int> với danh sách các số nguyên không dấu liên tiếp

X(n, t) // creates a sequence with n copies of t 
X(i, j) // creates a sequence from the elements of the interval [i, j) 

Tôi muốn sử dụng một trong những thứ hai cho một khoảng thời gian unsigned int, đó là

std::vector<unsigned int> l(1U, 10U); 

để có danh sách được khởi tạo với {1,2,...,9}. Những gì tôi nhận được, tuy nhiên, là một vector với một unsigned int với giá trị 10: - | Liệu biến thể thứ hai tồn tại, và nếu có, làm thế nào để ép buộc nó được gọi là?

Trả lời

10

Đọc lại các đoạn gần đó mô tả những gì mỗi người trong số các thông số. Cụ thể, cần đề cập rằng ij không phải là giá trị, nhưng trình lặp lại. Nhà xây dựng này thường được sử dụng để tạo bản sao của các loại container khác. Nếu bạn muốn nhận được một chuỗi các giá trị, số Boost library cung cấp counting iterator, thực hiện chính xác những gì bạn muốn.

std::vector<unsigned int> numbers(
    boost::counting_iterator<unsigned int>(0U), 
    boost::counting_iterator<unsigned int>(10U)); 
+0

cảm ơn, hoạt động như mong muốn! Cuốn sách là một chút không xác định đối với nhà xây dựng cụ thể đó, nhưng sau đó trên các chữ cái i, j là trong thực tế được sử dụng một cách rõ ràng cho các trình vòng lặp. Th. – Thomas

0

Không, biến thể đó không tồn tại. Hàm khởi tạo thứ hai khởi tạo một vectơ từ hai trình vòng lặp trỏ vào một chuỗi khác.

Dưới đây là một ví dụ về "hai iterator" constructor trong hành động:

int fill_data[4] = { 1, 2, 3, 4 }; 
std::vector<int> v(fill_data, fill_data + 4); 
+0

Cảm ơn yêu cầu chỉnh sửa, tôi đã đánh dấu không chính xác là không chính xác. :) Tôi đã sưa nó. –

2

Cách không tăng cường để thực hiện việc này bằng trình lặp tự tăng dần.

#include <vector> 
#include <iostream> 
#include <algorithm> 

static int NUM_ITEMS = 10; 

class gen_range { 
    public: 
     gen_range(int i) { idx = i; } 
     int operator()() { return (idx++); }; 

    int idx; 
}; 

int main() { 

    std::vector<int> x(NUM_ITEMS); 
    std::generate_n(x.begin(), NUM_ITEMS, gen_range(0)); 

    for (int i=0; i < x.size(); i++) { 
     std::cout << x[i] << std::endl; 
    } 
} 
1

C++ 11:

std::vector<int> idxs (n); 

std::generate_n (idxs.begin(), n, [] { static int i {1}; return i++; }); 
19

có ít nhất ba cách mà bạn có thể làm điều đó. Một đã được đề cập trước đó bởi Brian

//method 1 
generate(v.begin(), v.end(), [] { static int i {1}; return i++; });  

Bạn cũng có thể sử dụng std :: iota nếu bạn đang sử dụng C++ 11

//method 2 
iota(v.begin(), v.end(), 1); 

Hoặc thay vào đó bạn có thể khởi tạo container của bạn với 1s và sau đó làm một phần tổng cộng về điều đó. Tôi không nghĩ rằng bất kỳ ai cũng sẽ sử dụng phương thức thứ ba này :)

//method 3 
vector<int> v(n, 1);              
partial_sum(v.begin(), v.end(), v.begin()); 
+0

Phương pháp 3 khá thuận tiện nếu bạn muốn tạo một mảng chứa tổng tích lũy. Thêm một phần khác 'partial_sum (v.begin(), v.end(), v.begin())' và cho n = 5, bạn nhận được {1, 3, 6, 10, 15}. – lifebalance

+0

Lưu ý, 'tạo' ở đây sử dụng tĩnh. Đặt nó trong một hàm, gọi nó nhiều lần và nó sẽ tiếp tục đếm. Sử dụng 'ValueType i = {1}; std :: generate (đầu tiên, cuối cùng, [& i] {return i ++;}); 'thay thế. –

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