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

时间:2021-05-17 02:08:00

I'm following along with the OpenGL Super Bible 5th edition, and they define a vector(vector as in math) as

我正在跟随OpenGL超级圣经第5版,他们定义了一个矢量(矢量和数学一样)

typedef float   M3DVector3f[3];

I'm trying to add an instance of this to an std::vector(the 're sizable array' in c++), however I keep getting an error saying:

我正在尝试将这个实例添加到std :: vector(c ++中的'可调整大小的数组'),但是我不断收到错误说:

array initialization needs curly braces

Full Error

The way I defined the std::vector and the way I'm adding to it is:

我定义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);

I've gathered that the problem is with the vertices.push_back(v) call, because I don't get an error when I comment that out. Could someone explain to me and help me figure out why it won't let me add this vector to my vector?

我已经收集到了问题是vertices.push_back(v)调用,因为当我发表评论时我没有收到错误。有人可以向我解释并帮我弄清楚为什么它不允许我将这个向量添加到我的向量中?

4 个解决方案

#1


4  

Arrays cannot be (directly) copied or assigned, and standard containers requires types to be copyable and assignable.

无法(直接)复制或分配数组,标准容器要求类型可复制和分配。

However, you can (and probably should) do this instead:

但是,您可以(也可能应该)这样做:

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

Which is copyable and just as usable.

哪个是可复制的,也是可用的。

#2


1  

For starters, vertex[3] above should be vertex[2] as vertex[3] lies outside the upper bound of the array. However, that is not the crux of the issue here. The template instantiation of vector is being done with an array type. There is no default copy constructor, per se, for array types that will perform any copy deeper than the simple pointer copy. You may find that this works better if instead you try:

首先,上面的顶点[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);

There may be another, more elegant solution utilizing smart pointers to clean up each entry in the vector when you go to destroy it later. :-)

可能有另一个更优雅的解决方案,利用智能指针清理向量中的每个条目,以便以后销毁它。 :-)

#3


0  

Clarifying a bit on GMan's response above

澄清GMan上面的回应

The following code also throws the same error as you have got while doing a push_back.

以下代码也会抛出与执行push_back时相同的错误。

typedef float MYBUF[3];

int main(){
   MYBUF m1;

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

This is exactly what the vector::push_back does with any T. It tries to make a copy (and hence the term copyable) of the input argument and such a copy is not allowed by the C++ language for array types.

这正是vector :: push_back对任何T所做的。它试图创建输入参数的副本(因此也就是术语可复制),并且C ++语言不允许这样的副本用于数组类型。

#4


0  

Not sure how well it will suit you, but you could experiment with some less direct solution, like the following (which compiles without error):

不确定它适合你的程度,但你可以尝试一些不太直接的解决方案,如下所示(编译时没有错误):

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

#1


4  

Arrays cannot be (directly) copied or assigned, and standard containers requires types to be copyable and assignable.

无法(直接)复制或分配数组,标准容器要求类型可复制和分配。

However, you can (and probably should) do this instead:

但是,您可以(也可能应该)这样做:

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

Which is copyable and just as usable.

哪个是可复制的,也是可用的。

#2


1  

For starters, vertex[3] above should be vertex[2] as vertex[3] lies outside the upper bound of the array. However, that is not the crux of the issue here. The template instantiation of vector is being done with an array type. There is no default copy constructor, per se, for array types that will perform any copy deeper than the simple pointer copy. You may find that this works better if instead you try:

首先,上面的顶点[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);

There may be another, more elegant solution utilizing smart pointers to clean up each entry in the vector when you go to destroy it later. :-)

可能有另一个更优雅的解决方案,利用智能指针清理向量中的每个条目,以便以后销毁它。 :-)

#3


0  

Clarifying a bit on GMan's response above

澄清GMan上面的回应

The following code also throws the same error as you have got while doing a push_back.

以下代码也会抛出与执行push_back时相同的错误。

typedef float MYBUF[3];

int main(){
   MYBUF m1;

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

This is exactly what the vector::push_back does with any T. It tries to make a copy (and hence the term copyable) of the input argument and such a copy is not allowed by the C++ language for array types.

这正是vector :: push_back对任何T所做的。它试图创建输入参数的副本(因此也就是术语可复制),并且C ++语言不允许这样的副本用于数组类型。

#4


0  

Not sure how well it will suit you, but you could experiment with some less direct solution, like the following (which compiles without error):

不确定它适合你的程度,但你可以尝试一些不太直接的解决方案,如下所示(编译时没有错误):

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