Инициализация вектора std::со списком последовательных целых чисел без знака



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



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 :-| существует ли второй вариант, и если да, то как заставить его называться?

617   5  

5 ответов:

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

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

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

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

Вы также можете использовать std:: iota, если вы используете 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()); 

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

#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;
    }
}

C++11:

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

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

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

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

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

Comments

    Ничего не найдено.