在标准向量中将元素分配给 Eigen::Vector2d 会引发错误

Posted

技术标签:

【中文标题】在标准向量中将元素分配给 Eigen::Vector2d 会引发错误【英文标题】:Assigning elements to Eigen::Vector2d within std vector throws error 【发布时间】:2018-04-13 06:03:43 【问题描述】:

我浏览了几篇 *** 帖子,但没有发现此类错误。我正在尝试编写一个简单的类,它对Eigen 向量和矩阵进行一些操作。我创建了一个名为 MyClass 的类,它有一个名为 MyMethod 的方法。其代码如下

void MyClass::MyMethod(Eigen::Vector4f X, 
                       std::vector<Eigen::Vector2i> &pixelIndices,
                       std::vector<Eigen::Vector4f> vertices)

   // Do some preprocessing

   //Deleacring the std vector
   std::vector<Eigen::Vector2i> currTriangle(3);
   currTriangle[0] = Eigen::Vector2i(0); //Error occurs here

   // Do some more processing

从主函数执行方法时,上述语句发生错误。错误输出如下。

$: ./test1 
test1: /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:285: void Eigen::PlainObjectBase<Derived>::resize(Eigen::Index) [with Derived = Eigen::Matrix<int, 2, 1>; Eigen::Index = long int]: Assertion `((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0' failed.
Aborted (core dumped)

我知道使用带有 Eigen 的 STL 容器是有问题的,但正如 documentation 中提到的那样,问题似乎只存在于固定大小的可矢量化 Eigen 类型(即它们应该是 16 字节大小),但 Vector2i 不是这样的 Eigen 类型。在PlainObjectBase的resize()方法中调用了assert语句,这也很奇怪,因为我在代码的任何地方都没有使用过。

还有其他人遇到过这个错误吗?任何帮助将不胜感激。

更新: 错误似乎不是因为我使用了 std::vector。我对代码做了一些小改动。

  void MyClass::MyMethod(Eigen::Vector4f X, 
                         std::vector<Eigen::Vector2i> &pixelIndices,
                         std::vector<Eigen::Vector4f> vertices)

   // Do some preprocessing

   Eigen::Vector2i temp(0); //Same Error occures here also
   //Deleacring the std vector
   std::vector<Eigen::Vector2i> currTriangle(3);
   currTriangle[0] = Eigen::Vector2i(0);

   // Do some more processing

所以初始化Vector2i时似乎发生了错误。

【问题讨论】:

你不是告诉 Eigen 向量的大小为 2 和大小为 0 吗? @MarcGlisse 谢谢,这解决了我的问题,我错过了阅读文档,我认为 Vector2i(0) 会将向量中的所有值分配为零。但这不是构造函数的工作方式。需要注意的重要一点是,可以使用类似于 Vector4x(i1,i2,i3,i4) 的构造函数创建高达 Vector4x 的特征向量。与此类似,Vector2i(int i,int j) 是 Vector2i 的构造函数。 【参考方案1】:

正如@MarcGlisse 指出的那样,Vector2i(0) 告诉构造一个带有0 元素的Vector2i,这将在运行时失败。使用单个标量构造的固定大小的矩阵/向量将其解释为大小而不是值的原因是允许泛型函数,其中不清楚大小是动态的还是固定的:

template<int SizeAtCompileTime>
void foo()
    Eigen::Matrix<int, SizeAtCompileTime, 1> v(actualSize);
    // ...

有两种边界情况:将两个整数传递给具有两个元素的向量或将一个整数传递给具有一个元素的向量,将导致向量使用该值初始化如果 向量的标量类型可以从传递的整数类型隐式构造——否则,它将被解释为大小。

要解决您最初的问题,有几种选择:

Eigen::Vector2i temp1(Eigen::Vector2i::Zero());
Eigen::Vector2i temp2(0,0);

// initialize all elements with a Zero vector:
std::vector<Eigen::Vector2i> currTriangle(3, Eigen::Vector2i::Zero());

currTriangle[0].setZero(); // set 0th element to Zero vector
currTriangle[0].setConstant(0); // equivalent to setZero, but works for arbitrary constants
currTriangle[0].array() = 0; // .array() lets you do element-wise operations

【讨论】:

以上是关于在标准向量中将元素分配给 Eigen::Vector2d 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章

c++ 中将标准输入内容读入字符串或向量的最快方法

在Javascript中将类分配给数组

分配向量中元素的索引而不是其值

如何在Objective-C中将孩子分配给父母?

c++ 内存分配向量的指针

标准模板库中的向量(vector)