2010-11-23 7 views
6

estoy siguiendo, junto con la 5ª edición de OpenGL Súper Biblia, y que definen un vector (vector como en matemáticas) comoNecesito ayuda para añadir una matriz para un vector en C++

typedef float M3DVector3f[3]; 

Estoy intentando para agregar una instancia de este a un std :: vector (la 're gama considerable' en C++), sin embargo sigo obteniendo un error que dice:

array initialization needs curly braces 

Full Error

la forma en que se ha definido el std: : vector y la forma en que soy ad ding a que es:

std::vector<M3DVector3f> vertices; 

float vertex[3]; 
sscanf_s(line.c_str(), "%*s %f %f %f", &vertex[0], &vertex[1], &vertex[2]); 

M3DVector3f v = {vertex[0], vertex[1], vertex[3]}; 

vertices.push_back(v); 

que he reunido que el problema es con el vertices.push_back (v) la llamada, porque no me sale un error cuando comento eso. ¿Podría alguien explicarme y ayudarme a descubrir por qué no me deja agregar este vector a mi vector?

+1

+1 para un buen formato pregunta – Chubsdad

+0

sólo quiero Dile gracias a todos por ayudarme. Tomé el consejo de GMan y creé una nueva clase para todos mis vectores. Esto funcionó mucho mejor porque me permitió sobrecargar a los operadores, por lo que ahora mi código se ve limpio y ordenado. :) – krej

Respuesta

4

Las matrices no se pueden copiar ni asignar (directamente), y los contenedores estándar requieren que los tipos se puedan copiar y asignar.

Sin embargo, puede (y probablemente debería) hacer esto en su lugar:

struct M3DVector3f // a basic vector class 
{ 
    float x; 
    float y; 
    float z; 
}; 

Qué es copiable y tan utilizable.

+0

También es más legible ya que muestra lo que cada componente representa. –

+0

¿por qué la implementación no arroja un error al declarar 'vértices' en su lugar, si no cumple con los requisitos del contenedor? – Chubsdad

+0

@Chubsdad: Porque no tiene que ser así. El uso de estos requisitos no ocurre hasta la instanciación de las funciones que lo usan. (Esto es aún más importante en C++ 0x, donde los requisitos de los elementos se aplican por función). – GManNickG

1

Para los principiantes, el vértice [3] anterior debe ser el vértice [2] ya que el vértice [3] se encuentra fuera del límite superior de la matriz. Sin embargo, ese no es el quid de la cuestión aquí. La instanciación de plantilla de vector se está haciendo con un tipo de matriz. No existe un constructor de copia predeterminado, per se, para los tipos de matriz que realizarán cualquier copia más profunda que la simple copia de puntero. Es posible que esto funciona mejor si en vez de intentar:

std::vector<M3DVector3f*> vertices; 
M3DVector3f* v = new M3DVector3f; 

sscanf_s(line.c_str(), "%*s %f %f %f", &((*v)[0]), &((*v)[1]), &((*v)[2])); 

vertices.push_back(v); 

Puede haber otra solución más elegante que utiliza punteros inteligentes para limpiar cada entrada en el vector cuando se va a destruir más tarde. :-)

+0

Intenté esto, sin embargo el uso del 'nuevo' me da este error: no puedo convertir 'float *' a 'M3DVector3f (*)' – krej

0

Aclarando un poco en la respuesta de GMan anterior

El siguiente código también se lanza el mismo error que usted tiene mientras se hace un push_back.

typedef float MYBUF[3]; 

int main(){ 
    MYBUF m1; 

    MYBUF m2(m1);  // Same Error as in OP 
} 

Esto es exactamente lo que el vector :: push_back hace con cualquier T. Se trata de hacer una copia (y de ahí el término copiable) del argumento de entrada y una copia no está permitida por el lenguaje C++ para tipos de matriz

0

No está seguro de lo bien que se adapte a usted, pero usted podría experimentar con alguna solución menos directa, como la siguiente (que se compila sin errores):

#include <iostream> 
#include <vector> 

typedef float M3DVector3f[3]; 

struct X 
{ 
    X(M3DVector3f& p) { x_[0] = p[0]; x_[1] = p[1]; x_[2] = p[2]; } 
    operator M3DVector3f&() { return x_; } 
    M3DVector3f x_; 
}; 

int main() 
{ 
    M3DVector3f v = { 1, 2, 3 }; 
    std::vector<X> xs; 
    xs.push_back(v); 
} 
Cuestiones relacionadas