Qual é a maneira mais simples de converter array em vetor?

92

Qual é a maneira mais simples de converter array em vetor?

void test(vector<int> _array)
{
  ...
}

int x[3]={1, 2, 3};
test(x); // Syntax error.

Eu quero converter x de matriz int em vetor de maneira mais simples.

Amir Saniyan
fonte

Respostas:

138

Use o vectorconstrutor que leva dois iteradores, observe que os ponteiros são iteradores válidos e use a conversão implícita de matrizes em ponteiros:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);

ou

test(std::vector<int>(x, x + sizeof x / sizeof x[0]));

onde sizeof x / sizeof x[0]está obviamente 3neste contexto; é a maneira genérica de obter o número de elementos em uma matriz. Observe que x + sizeof x / sizeof x[0]aponta um elemento além do último elemento.

Fred Foo
fonte
1
Você pode explicar isso, por favor? Eu já li que vector<int> a(5,10);significa make room for 5 int` e inicializo-os com 10. Mas como o seu x, x + ... funciona? você pode explicar?
Asif Mushtaq de
1
@UnKnown em vez de selecionar vector<int>::vector(size_type, int), ele seleciona vector<int>::vector(int*, int*), o que copia o intervalo indicado por esse par de ponteiros. O primeiro é sobrecarga (2), o segundo é sobrecarga (4) aqui
Caleth
1
Em c ++ 11, std :: Ext é melhor do que o método sizeof. sizeof x / sizeof x[0] == std::extent<decltype(x)>::value
Isaac Pascual
112

Pessoalmente, gosto bastante da abordagem C ++ 2011 porque não requer que você use sizeof()nem se lembre de ajustar os limites do array se você alterar os limites do array (e você pode definir a função relevante no C ++ 2003 se quiser também ):

#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));

Obviamente, com C ++ 2011 você pode querer usar listas de inicializadores de qualquer maneira:

std::vector<int> v({ 1, 2, 3, 4, 5 });
Dietmar Kühl
fonte
2
ele copia o array ou apenas aponta para ele? estou preocupado com o desempenho
kirill_igum
2
std::vector<T>sempre possui os Tobjetos. Isso tem duas implicações: ao inserir um objeto em um vetor, eles são copiados e colocados na memória. Para objetos razoavelmente pequenos, por exemplo, sequências de strings curtas, a colocação é um grande ganho de desempenho. Se seus objetos são grandes e caros para copiar, você pode querer armazenar ponteiros [de alguma forma gerenciados por recursos] para os objetos. Qual abordagem é mais eficiente depende dos objetos, mas você tem a escolha.
Dietmar Kühl
então, se eu quiser fazer a interface de bibliotecas c ++ e ac e copiar do c-array para o vetor e vice-versa, não há como pagar a penalidade de 2 cópias? (estou usando a biblioteca eigen e gsl)
kirill_igum
16

Os ponteiros podem ser usados ​​como qualquer outro iterador:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)
Rafał Rawicki
fonte
2
Na vida real, você pode querer abstrair o tamanho do array, por exemplo, usando const size_t X_SIZE = 3;para denotar o tamanho do array ou calculá-lo a partir de sizeof. Omiti essa parte por uma questão de legibilidade.
Rafał Rawicki
11

Você está fazendo a pergunta errada aqui - em vez de forçar tudo em um vetor, pergunte como você pode converter teste em trabalho com iteradores em vez de um contêiner específico. Você também pode fornecer uma sobrecarga para manter a compatibilidade (e lidar com outros contêineres ao mesmo tempo gratuitamente):

void test(const std::vector<int>& in) {
  // Iterate over vector and do whatever
}

torna-se:

template <typename Iterator>
void test(Iterator begin, const Iterator end) {
    // Iterate over range and do whatever
}

template <typename Container>
void test(const Container& in) {
    test(std::begin(in), std::end(in));
}

O que permite que você:

int x[3]={1, 2, 3};
test(x); // Now correct

( Demonstração Ideone )

Flexo
fonte
"em vez de forçar tudo em um vetor, pergunte como você pode converter o teste para trabalhar com iteradores em vez de um contêiner específico." Por que isso é melhor?
aquirdturtle
1
@aquirdturtle porque agora, em vez de apenas suportar vetores, você oferece suporte a listas e matrizes e aumenta contêineres e transforma iteradores e intervalos e ....
Flexo
2
e você não precisou copiar os dados
Lightness Races in Orbit
2

Uma maneira simples pode ser o uso de uma assign()função pré-definida na vectoraula.

por exemplo

array[5]={1,2,3,4,5};

vector<int> v;
v.assign(array, array+5); // 5 is size of array.
3251_ali
fonte
2
Equivalente ao uso do ctor, que foi mencionado em respostas existentes há cerca de sete anos. Não adiciona nada ...
Lightness Races in Orbit