我需要帮助在C++中将数组添加到向量中。

5

我正在按照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)这个调用上,因为当我将其注释掉时,就不会出现错误。有人能向我解释并帮助我弄清楚为什么它不允许我将这个向量添加到我的向量中吗?


1
+1 用于格式良好的问题 - Chubsdad
我想对所有帮助过我的人表示感谢。我采纳了GMan的建议,为我的所有向量创建了一个新类。这样做效果更好,因为它让我可以重载运算符,现在我的代码看起来整洁漂亮。 :) - krej
4个回答

4

数组不能直接复制或分配,标准容器要求类型可复制和可分配。

然而,您可以使用以下方法代替:

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

这个元素是可以被复制并且同样可用的。


如果声明“vertices”的实现不符合容器的要求,为什么不会抛出错误? - Chubsdad
@Chubsdad:因为它不需要。这些要求的使用直到使用它的函数实例化时才会发生。(在C++0x中,元素要求是基于每个函数应用的,这更加重要。) - GManNickG
@GMan:从设计角度来看,我更希望声明本身失败,而不是将惊喜元素推到实际使用点,特别是对于一些像size()这样的琐碎函数,几乎无法处理这样的声明。看起来这是语言机制的限制。 - Chubsdad
起初我这么写是可以的,但后来我开始使用顶点进行加减运算,OpenGL超级圣经的作者给了我一个带有M3DVector3f的3D数学库,并且他们制作了添加/减去等函数以及点积等。重做这些函数好像有点傻,所以我决定切换到使用他们的M3DVector3f,这样我就可以使用他们的库了。有没有什么办法可以强制让它工作?如果不行,能否推荐一个好的3D数学库,这样我就不需要自己制作了? - krej
@user:不,没有直接使用数组的方法使其工作,你需要将它们放入一个结构体中或者做其他事情。我不知道有哪些简单的数学库,但是老实说,我建议自己编写一个。 - GManNickG
显示剩余2条评论

1
对于初学者来说,上面的vertex[3]应该是vertex[2],因为vertex[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);

可能还有另一种更优雅的解决方案,利用智能指针在稍后销毁每个向量条目时进行清理。:-)


我尝试了这个,但使用“new”会给我带来这个错误:无法将“float ”转换为“M3DVector3f ()”。 - krej

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++语言不允许数组类型进行这样的复制。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接