我正在跟随OpenGL超级圣经第5版,他们定义了一个矢量(矢量和数学一样)
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)调用上,因为当我发表评论时我没有收到错误。有人可以向我解释并帮我弄清楚为什么它不会让我把这个载体添加到我的载体中?
答案 0 :(得分:4)
无法(直接)复制或分配数组,标准容器要求类型可复制和分配。
但是,您可以(也可能应该)这样做:
struct M3DVector3f // a basic vector class
{
float x;
float y;
float z;
};
哪个 可以复制并且同样可用。
答案 1 :(得分:1)
首先,上面的顶点[3]应该是顶点[2],因为顶点[3]位于数组的上界之外。但是,这不是问题的症结所在。 vector的模板实例化是使用数组类型完成的。对于将执行比简单指针复制更深的任何复制的数组类型,本身没有默认的复制构造函数。您可能会发现,如果您尝试这样做,效果会更好:
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);
当您稍后破坏它时,可能会有另一个更优雅的解决方案利用智能指针来清理向量中的每个条目。 : - )
答案 2 :(得分:0)
澄清GMan上面的回应
以下代码也会抛出与执行push_back时相同的错误。
typedef float MYBUF[3];
int main(){
MYBUF m1;
MYBUF m2(m1); // Same Error as in OP
}
这正是vector :: push_back对任何T所做的。它试图创建输入参数的副本(因此也就是术语可复制),并且C ++语言不允许这样的副本用于数组类型。 / p>
答案 3 :(得分:0)
不确定它是否适合您,但您可以尝试一些不那么直接的解决方案,如下所示(编译时没有错误):
#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);
}