调用 segment() 后未分配的 Eigen::VectorXd 对象会发生什么?

What happens to unassigned `Eigen::VectorXd` object following a call to `segment()`?

我有一个 class Foo 存储匹配维度的特征 MatrixXdVectorXd 并提供一个执行矩阵向量的简单函数 .mult()乘法。我有一个调用 mult() 的函数,获取返回向量的一部分,并进行一些进一步的计算。这是代码的简化版本:

#include <Eigen/Dense>

class Foo {
  Eigen::MatrixXd X;
  Eigen::VectorXd v;
public:
  Foo() {
    X.resize(2, 2);
    v.resize(2);
    X << 1, 4, 2, 4;
    v << -1, 1;
  }
  Eigen::VectorXd mult() {
    return X * v;
  }
};

Eigen::VectorXd bar() {
  Foo f;
  Eigen::VectorXd val = f.mult().segment(1, 1);
// Use val to do some computation.
  Eigen::VectorXd ret = val.array() + 2;
  return ret;
}

在代码审查期间,有人评论说这可能会导致存储 f.mult() 结果的 unnamed/temp 变量的引用悬空。并且提出了一个关于未分配名称的临时变量的生命周期的一般性问题。

如果我对RVO理解正确的话,会在栈上创建一个临时对象,其地址会传递给f.mult(),然后将X * v的结果存储到传入的内存地址中.当 bar() 终止时,这个临时对象将超出范围。不应该有任何悬而未决的引用或关于临时和未分配变量的范围的担忧。但我不太确定。

Eigen 是一个优雅但复杂的库,我希望确保我尽可能安全地使用它。提前致谢!

你所做的是节省(但效率低下)。

f.mult() returns 一个 Eigen::VectorXd 对象的值,它存在于语句的其余部分(“直到下一个 ;”)。因此调用 segment() 是安全的,只要您将该结果存储到 VectorXd(而不是 auto 对象)。

要获得 matrix-vector 产品的一部分,将矩阵的相应 sub-block 相乘会更有效,即:

(X*v).segment(a,b) == X.rows(a,b) * v