没有从价值到价值的已知表达& ...为什么?

时间:2014-05-04 05:28:13

标签: c++ eigen

我尝试编写一个以ColXpr值作为输入的函数:

typedef Eigen::Array<float, Eigen::Dynamic, Eigen::Dynamic> Signal2D;

void Threshold(Signal2D::ColXpr& params)
{
  params = (params >= 0.0f).template cast<float>();
}

当我尝试调用此函数时,我会执行以下操作:

Signal2D arr;
// fill it with stuff
Threshold(arr.col(0));

然后我得到了这个编译错误:

src/core/Neuron.h:91:14: note:   no known conversion for argument 1 from ‘Eigen::DenseBase<Eigen::Array<float, -1, -1> >::ColXpr {aka Eigen::Block<Eigen::Array<float, -1, -1>, -1, 1, true>}’ to ‘Eigen::DenseBase<Eigen::Array<float, -1, -1> >::ColXpr& {aka Eigen::Block<Eigen::Array<float, -1, -1>, -1, 1, true>&}’
make: *** [src/training/Fibonacci.o] Error 1

如果不重新发布导致此问题的整个代码系列,当编译器说no known conversion for argument from Value to Value&时,是否有人可以解释的含义?为什么在这种情况下无法获得引用?请注意,我发现了与this指针相关的类似问题,我已在此处发布:

error: no match for 'operator<<' using boost::serialisation

这可能是GCC 4.9.0的一些特点还是我在这里做错了什么?如果你需要看一个独立的例子,请告诉我,这需要一段时间才能拼凑起来,我认为这里可能有足够的信息指出我的一个明显的错误。

3 个答案:

答案 0 :(得分:3)

在C ++中,临时对象无法绑定到非const引用。

我假设arr.col(0)按值返回一个对象。返回的值是临时对象。这意味着它无法匹配T &类型的参数。

一个解决方案:

auto temp = arr.col(0);
Threshold(temp);

我想知道您是否打算让arr.col()返回引用?

答案 1 :(得分:3)

要完成以前的答案,你可能正在寻找Ref<>类,它允许你编写一个接受矩阵列的函数和没有模板和副本的矢量:

void threshold(Ref<ArrayXf> params) {
    params = (params >= 0 ).cast<float>();
}
ArrayXf  a;
ArrayXXf A;
/* ... */
threshold(a);
threshold(A.col(j));

答案 2 :(得分:1)

添加到上面的答案:

特征返回表达式是临时表达式。例如。 ColXpr只是一个小的可复制对象,可让您访问数组数据。它由值ColXpr col(...)返回。您可以使用const引用捕获ColX​​pr临时,但不能捕获。

但是你可以写:

void Threshold(Matrix::ColXpr col);

通常,修改函数中的特征表达式是不受欢迎的。 首选方法是编写一元/二元函子/ lambdas,例如:

array.col(i) = array.col(i).unaryExpr(
  [](const float &value) {
    return float(value >= 0); 
  }
);

顺便说一句,如果你打算编写泛型特征函数,可以使用Eigen::EigenBase<B>作为参数来捕获任何特征表达式,参见http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

Boost序列化也需要非临时引用,甚至操作数也被写入存档。