0

Есть ли способ, чтобы построить новый std::vector с неинициализированных (ненулевыми) значениями или даже красивее через генератор (похоже на std::generate_n()) аргумент конструктора, отображающий его желательно нестандартные (непостоянные) значения без сначала инициализируют все элементы до нуля? Это потому, что я хочу, чтобы (random) mockup-creation api был максимально эффективным с точки зрения местоположения, тем самым только один раз создавая элементы контейнера. Не было бы опрятно иметь генератор-конструктор для std::vector (и, возможно, других) ?! Почему C++ уже не добавила это в стандарт?непостоянной Генератор однопроходная Инициализация во время строительства

Следующий конструктор типа функция C иллюстрирует с однократной записью поведения я ищу для пользовательской инициализации строительства std::vector:

// Allocate-and-Generate a random int array of length \p n. 
int * gen_rand(size_t n) 
{ 
    int *v = malloc(n); // allocate only 
    for (size_t i=0; i<n; i++) { 
    v[i] = rand(); // first write 
    } 
} 

Я считаю, это сводится к поведению СТЛ Allocator используемого так как он отвечает за запись начальных нулей (или нет).

Если мы используем конструктор std::vector с итераторами, нам сначала нужно выделить и записать случайные значения где-то еще, что еще хуже, чем с использованием push_back().

+0

Итераторы - это то, как вы это делаете. Посмотрите http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/counting_iterator.html – Lalaland

+0

@EthanSteinberg: решение итератора для std :: vector либо требует использования 'push_back()', что меньше эффективны или снова приводят к записи в элементы дважды. Для других, таких как 'std :: list', итераторы могут быть хорошим решением. –

+0

Вы можете использовать итераторы в конструкторе ... – Lalaland

ответ

3

Вы можете предшествовать использованию генератора с вызовом vector::reserve. Это будет иметь то же поведение, что и код C, который вы показываете. Вам все равно придется использовать back_insert_iterator, так как размер vector по-прежнему будет равен нулю.

#include <vector> 
#include <cstdlib> 
#include <algorithm> 
#include <iterator> 
#include <iostream> 


int main() 
{ 
    std::vector<int> v; 
    v.reserve(10); 
    std::generate_n(std::back_inserter(v), 10, []() { return rand(); }); 
    for(auto x : v) 
    std::cout << x << std::endl; 
    // unsafe version 
    std::vector<int> v2; 
    // 10 uninitialized integers 
    v2.resize(10); 
    // make sure never to write more than the exact amount, otherwise this will be UB 
    std::generate_n(v.begin(), 10, []() { return rand(); }); 

    return 0; 
} 
+0

Возможно, некоторые дополнительные условные утверждения относительно проверки размера вектора будут добавлены во время итерации в версии C++, но не будут перераспределения. Достаточно близко. –

+0

@ Nordlöw Размер вектора проверяется только на операцию push_back. 'resize' будет проверять только' capacity'. Я добавил версию, которая позволяет избежать этого, хотя я считаю его небезопасным. – pmr

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

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