Мне нужна помощь в добавлении массива в вектор в C ++ - PullRequest
6 голосов
/ 23 ноября 2010

Я следую вместе с 5-й версией OpenGL Super Bible, и они определяют вектор (вектор как в математике) как

typedef float   M3DVector3f[3];

Я пытаюсь добавить экземпляр этого в std :: vector ('массив большого размера' в c ++), однако я получаю сообщение об ошибке:

array initialization needs curly braces

Полная ошибка

То, как я определил std :: vector, и то, как я к нему добавляю:

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);

Я понял, что проблема в вызове vertices.push_back (v), потому что я не получаю сообщение об ошибке, когда закомментирую это. Может ли кто-нибудь объяснить мне и помочь мне понять, почему он не позволяет мне добавить этот вектор в мой вектор?

Ответы [ 4 ]

4 голосов
/ 23 ноября 2010

Массивы нельзя (напрямую) копировать или назначать, а для стандартных контейнеров необходимо, чтобы типы были копируемыми и назначаемыми.

Однако вы можете (и, вероятно, должны) сделать это вместо:

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

Который является копируемым и таким же пригодным для использования.

1 голос
/ 23 ноября 2010

Для начала вершина [3] выше должна быть вершиной [2], так как вершина [3] находится вне верхней границы массива. Однако, это не суть проблемы здесь. Создание шаблона вектора выполняется с типом массива. Для типов массивов по умолчанию не существует конструктора копирования по умолчанию, который будет выполнять любую копию глубже, чем простая копия указателя. Вы можете обнаружить, что это работает лучше, если вместо этого вы попробуете:

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);

Может быть другое, более элегантное решение, использующее умные указатели для очистки каждой записи в векторе, когда вы собираетесь уничтожить ее позже. : -)

0 голосов
/ 23 ноября 2010

Не уверен, насколько он вам подходит, но вы можете поэкспериментировать с каким-то менее прямым решением, например следующим (которое компилируется без ошибок):

#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);
}
0 голосов
/ 23 ноября 2010

Разъяснение немного ответа GMan выше

Следующий код также выдает ту же ошибку, что и вы, когда выполняете push_back.

typedef float MYBUF[3];

int main(){
   MYBUF m1;

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

Это именно то, что вектор ::push_back делает с любым T. Он пытается сделать копию (и, следовательно, термин копируемый) входного аргумента, и такая копия не разрешена языком C ++ для типов массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...