Preciso copiar std::set
para std::vector
:
std::set <double> input;
input.insert(5);
input.insert(6);
std::vector <double> output;
std::copy(input.begin(), input.end(), output.begin()); //Error: Vector iterator not dereferencable
Onde está o problema?
assign()
função:output.assign(input.begin(), input.end());
Respostas:
Você precisa usar um
back_inserter
:std::copy
não adiciona elementos ao contêiner no qual você está inserindo: não pode; ele possui apenas um iterador no contêiner. Por esse motivo, se você passar diretamente um iterador de saídastd::copy
, verifique se ele aponta para um intervalo que seja pelo menos grande o suficiente para manter o intervalo de entrada.std::back_inserter
cria um iterador de saída que chamapush_back
um contêiner para cada elemento, para que cada elemento seja inserido no contêiner. Como alternativa, você poderia ter criado um número suficiente de elementosstd::vector
para manter o intervalo que está sendo copiado:Ou você pode usar o
std::vector
construtor range:fonte
output.insert(output.end(), input.begin(), input.end());
?output.insert(output.cend(), input.cbegin(), input.cend());
que você acha? Obrigado.input,size()
entradas vazias e acrescenta os anexos depois disso. Eu acho que você pretende usarstd::vector<double> output; output.reserve(input.size()); std::copy(...);
.Basta usar o construtor para o vetor que leva os iteradores:
Supõe que você deseja apenas o conteúdo de s em v, e não há nada em v antes de copiar os dados para ele.
fonte
aqui está outra alternativa usando
vector::assign
:fonte
Você não reservou espaço suficiente no seu objeto de vetor para armazenar o conteúdo do seu conjunto.
fonte
Eu acho que a maneira mais eficiente é pré-alocar e depois substituir elementos:
Dessa forma, chamaremos apenas o construtor de cópia para cada elemento, em vez de chamar o construtor padrão primeiro e, em seguida, o operador de atribuição de cópia para outras soluções listadas acima. Mais esclarecimentos abaixo.
back_inserter pode ser usado, mas chamará push_back () no vetor ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator ). emplace_back () é mais eficiente porque evita a criação de um temporário ao usar push_back () . Não é um problema com tipos trivialmente construídos, mas será uma implicação de desempenho para tipos não-trivialmente construídos (por exemplo, std :: string).
Precisamos evitar a construção de um vetor com o argumento size, que faz com que todos os elementos sejam construídos por padrão (por nada). Como na solução usando std :: copy () , por exemplo.
E, finalmente, o método vector :: assign () ou o construtor que utiliza o intervalo do iterador não são boas opções porque invocam std :: distance () (para saber o número de elementos) nos iteradores de conjunto . Isso causará iteração adicional indesejada nos elementos definidos , pois o conjunto é a estrutura de dados da Árvore de Pesquisa Binária e não implementa iteradores de acesso aleatório.
Espero que ajude.
fonte
back_inserter
não precisa ser usadostd::copy
não pode ser usado para inserir em um recipiente vazio. Para fazer isso, você precisa usar um insert_iterator da seguinte forma:fonte