2014-05-04 105 views
2

我试图写一个函数,它接受一个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的一些特点还是我错在这里做什么?请让我知道,如果你需要看到一个独立的例子,它将需要一段时间来拼凑在一起,我认为这里可能有足够的信息来指出我的一个明显的错误。

+0

让我猜猜 - 'arr.col()'返回一个'Signal2D'? –

+0

@MattMcNabb否,'Eigen :: Array :: col()'返回'Eigen :: ColXpr'。我的示例代码中存在一个错误(固定),请参阅http://eigen.tuxfamily.org/dox/classEigen_1_1DenseBase.html#a58c77695de3b33405f01f2fdf3dc389d – arman

+0

与Signal2D :: ColXpr相同吗? (我看你刚刚编辑了什么'阈值“) –

回答

3

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

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

一个解决方案:

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

我不知道你是否打算arr.col()返回一个参考?

+0

是的,我做了...看起来我需要建立在我的Eigen上,在这里稍微有所欠缺。 – arman

1

添加到上述答案中:

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

但是你可以写:

void Threshold(Matrix::ColXpr col); 

一般来说,它是令人难以接受的修改在本征函数表达。 的首选方法是写一元/二元仿函数/ lambda表达式如:

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

顺便说一句,如果你打算编写普通的本征函数,使用Eigen::EigenBase<B>作为参数来捕捉任何固有的表情,看到http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

加速序列化也需要非临时引用,即使操作数正被写入存档。

3

要完成以前的答案,你可能寻找Ref<>类,这将让你写一个接受矩阵的列和向量没有模板,也没有拷贝功能:

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