2011-12-30 8 views
11

Sé que puede hacer: &theVector[0], pero ¿es este estándar? ¿Está garantizado este comportamiento siempre?Conversión de un vector en una matriz: ¿existe una forma "estándar" de hacer esto?

Si no, ¿hay una forma mejor y menos "hackosa" de hacer esto?

+5

En C++ 11 la forma correcta es 'theVector.data()'. – ildjarn

+3

Tenga en cuenta que '& theVector [0]' no genera una * matriz *, sino un * puntero *. Los punteros y matrices son cosas diferentes en el idioma, con diferentes tipos. No puede * convertir * un vector en una matriz de ninguna manera estándar, aunque su enfoque es una forma estándar de obtener un * puntero * a los datos. –

+0

No llamaría esto un hackish ya que la compatibilidad con las API de C que usan punteros de matriz fue una decisión de diseño en el STL. La alternativa, que a veces se ve & * theVector.begin(), no debe utilizarse. – aselle

Respuesta

20

Sí, ese comportamiento está garantizado. Aunque no puedo citarlo, el estándar garantiza que los elementos vectoriales se almacenen consecutivamente en la memoria para permitir esto.

Hay una excepción sin embargo:

No funcionará para vector<bool> debido a una especialización de plantilla.

http://en.wikipedia.org/wiki/Sequence_container_%28C%2B%2B%29#Specialization_for_bool

Esta especialización intentos de salvar la memoria de embalaje bools juntos en un campo de bits. Sin embargo, rompe algunas semánticas y, como tal, &theVector[0] en un vector<bool> no funcionará.

En cualquier caso, vector<bool> es ampliamente considered to be a mistake por lo que la alternativa es usar std::deque<bool> en su lugar.

+0

Supongo que en ese caso, simplemente tendría que copiarlo usando 'copy' o algo así? –

+1

Hay otra excepción: si el vector está vacío, no puede usar el operador de subíndice en él. –

+1

@JonathanLingle Sí, puede usar 'std :: copy()' para hacer eso. – Mysticial

-1

¿Una manera menos "hackosa"? Bien podría simplemente copiar:

#include <iostream> 
#include <vector> 
using namespace std; 



int main() 
{ 
    vector<int> vect0r; 
    int array[100]; 

    //Fill vector 
    for(int i = 0; i < 10 ; i++) vect0r.push_back(i) ; 

    //Copy vector to array[ ] 
    for( i = 0; i < vect0r.size(); i++) array[i] = vect0r[i]; 

    //Dispay array[ ] 
    for( i = 0; i < vect0r.size(); i++) cout<< array[i] <<" \n"; 

    cout<<" \n"; 

return 0; 
} 

Más aquí: How to convert vector to array in C++

+0

'int matriz [vec.size()] ; 'no es legal C++. – ildjarn

+0

La codificación 'MAGIC_NUMBER' es técnicamente legal, pero algo muy malo. Eso no es mejor – Puppy

13

C++ 11 proporciona el método data() en std::vector que devuelve un T*. Esto le permite hacer:

#include <iostream> 
#include <vector> 

int main() 
{ 
    std::vector<int> vector = {1,2,3,4,5}; 
    int* array = vector.data(); 
    std::cout << array[4] << std::endl; //Prints '5' 
} 

Sin embargo, hacer esto (o cualquiera de los métodos mencionados anteriormente) puede ser peligroso ya que el puntero podría ser válida si se cambia el tamaño del vector. Esto se puede mostrar con:

#include <iostream> 
#include <vector> 

int main() 
{ 
    std::vector<int> vector = {1,2,3,4,5}; 
    int* array = vector.data(); 

    vector.resize(100); //This will reserve more memory and move the internal array 

    //This _may_ end up taking the place of the old array  
    std::vector<int> other = {6,7,8,9,10}; 

    std::cout << array[4] << std::endl; //_May_ now print '10' 
} 

Esto podría bloquear o hacer casi cualquier cosa, así que ten cuidado al usar esto.

0

Podemos hacerlo utilizando el método data(). C++ 11 proporciona este método. Devuelve un puntero al primer elemento en el vector. vector Incluso si está vacío, podemos llamar a esta función por sí mismo sin problemas

vector<int>v; 
    int *arr = v.data(); 
Cuestiones relacionadas