2015-10-18 82 views
2

我正在尝试编写一个函数,它只接受通过const引用传递的左值Eigen表达式。我的第一个想法是只保留过载const Eigen::MatrixBase<Derived>&deleteEigen::MatrixBase<Derived>&&之一。令我惊讶的是,delete d函数不是超载候选集的一部分。所以,我试图下面禁用Eigen表达式与const引用的临时绑定

#include <iostream> 
#include <Eigen/Dense> 

#define PRINT_MY_NAME std::cout << __PRETTY_FUNCTION__ << '\n' 

template<typename Derived> 
void f(const Eigen::MatrixBase<Derived>&) // (1) 
{ 
    PRINT_MY_NAME; 
} 

template<typename Derived> 
void f(Eigen::MatrixBase<Derived>&&)  // (2) 
{ 
    PRINT_MY_NAME; 
} 

int main() 
{ 
    Eigen::MatrixXd A; 

    f(A);  // invokes (1) 
    f(A + A); // invokes also (1) !!! 
} 

,其输出(gcc5.2)

空隙F(const的本征:: MatrixBase &)[所述代码与衍生=征::矩阵<双,-1, -1>]

空隙F(const的本征:: MatrixBase &)与衍生=征:: CwiseBinaryOp <征::内部:: scalar_sum_op <双>,常量征::矩阵<双,-1, - 1>,const Eigen :: Matrix < double,-1,-1 >>]

如此明显的右值过载没有考虑。现在我清楚地知道第二个不是更好的匹配,因为我传递了一个右值Eigen表达式,它可以转换为Eigen::MatrixBase<>,但不是完全相同的类型。现在我的问题:

  • 如何禁用或检测右值Eigen表达式作为参数f传递?问题是表达式可以具有任意类型(Eigen使用表达式模板),如CwiseBinaryOp<...CwiseBinaryOp<...>>等等。这是一个更大的问题的一部分,我有一个实用的类似于make的函数,该函数接受一个左值并将其绑定到类中的const引用表达式。如果表达式是一个右值,那么所有的赌注都是关闭的,因为引用绑定不是通过构造函数参数传播的,所以我想禁止传递右值Eigen表达式。
+0

有趣的是,我没有相同的[结果](http://ideone.com/xMeQNJ),而试图让一个小例子。 –

+0

@PiotrSkotnicki可能这就是为什么不考虑第二次过载的原因。问题是我如何执行它? – vsoftco

+1

@MatthieuM。我相信它与Eigen的“胆量”有关,以及它如何实现表达式模板。你是否也尝试了上面的确切代码?如果你得到(2)调用,我会非常惊讶。 – vsoftco

回答

2

我想我发现了什么事情:表达模板A + A的结果是const,所以出现了CV错配。添加const到第二个重载做的:

template<typename Derived> 
void f(const Eigen::MatrixBase<Derived>&&)  // (2) 
{ 
    PRINT_MY_NAME; 
} 
+0

该死的......他们没有得到关于返回类型的const的备忘录:x –