2015-10-18 85 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 –