2012-01-13 3 views
9

Я хочу использовать специальный метод для инициализации std::vector<unsigned int>, который описан в книге на C++, которую я использую в качестве ссылки (немецкая книга Der C++ Программист "Ульриха Браймана, в случае, если это имеет значение). В этой книге представлен раздел о типах последовательностей STL, относящийся, в частности, к list, vector и deque. В этом разделе он пишет, что есть две специальные конструкторы таких типов последовательностей, а именно, если X относится к такому типу,Инициализация std :: vector <unsigned int> со списком последовательных целых чисел без знака

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) 

Я хочу использовать вторую для интервала unsigned int, то есть

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

, чтобы получить список, инициализированный {1,2,...,9}. Однако я получаю вектор с одним unsigned int со значением 10: - | Существует ли второй вариант, и если да, то как я могу заставить его его называть?

ответ

10

Перечитайте абзацы рядом там, описывающие то, что каждый из параметров. В частности, следует отметить, что i и j не являются значениями, но итераторами. Этот конструктор очень часто используется для создания копий других типов контейнеров. Если вы хотите получить последовательность значений, то Boost library предоставляет counting iterator, который делает именно то, что вы хотите.

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

спасибо, работает по вашему желанию! Книга немного неспецифична в отношении этого конкретного конструктора, но позже буквы i, j фактически используются явно для итераторов. Th. – Thomas

0

Нет, этого варианта не существует. Второй конструктор инициализирует вектор из двух итераторов, которые указывают на другую последовательность.

Вот пример «два-итератора» конструктор в действии:

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

Спасибо за запрос на редактирование, я неправильно указал его как неправильный. :) Я исправил это. –

2

Невозбужденный способ сделать это с помощью самоинструментального итератора.

#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

есть по крайней мере три способа, которые вы можете сделать это. Один из них был уже упоминалось ранее Брайан

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

Вы также можете использовать зЬй :: йота, если вы используете C++ 11

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

Или вместо этого вы можете инициализировать контейнер с 1s, а затем сделать частичный сумма на это. Я не думаю, что кто-нибудь будет использовать этот третий метод в любом случае :)

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

Метод 3 довольно удобен, если вы хотите сгенерировать массив, содержащий совокупные суммы. Добавьте еще один 'partial_sum (v.begin(), v.end(), v.begin())' и для n = 5 вы получите {1, 3, 6, 10, 15}. – lifebalance

+0

Примечание: 'generate' здесь использует static. Поместите его в функцию, назовите его несколько раз, и он будет продолжать подсчет. Используйте 'ValueType i = {1}; std :: generate (first, last, [& i] {return i ++;}); вместо этого. –

 Смежные вопросы

  • Нет связанных вопросов^_^