Eigen是常用的線性代數計算庫,而且是header-only,意即其只有頭文件,沒有對應的cpp/cc文件。Eigen目前仍在不斷穩定的迭代,截止目前迭代到3.4.0。Eigen擁有完善的文檔,高質量的代碼,是開源軟件的優秀典范。一次在項目中用到Eigen並且在學習模板元編程時,接觸到CRTP等概念,遂激發興趣想深入了解Eigen並將自己閱讀Eigen過程中總結記錄下來。
Eigen的目錄結構分為兩大部分src和頭文件,如下圖所示。頭文件按照具體功能划分,用戶使用時將其包含在內即可,如客戶想使用特征值計算,那么就直接#include<Eigen/Eigenvalues>即可;src是對應的實現。
src雖然是對應的實現,但是卻沒有一個cpp/cc文件,那么這么多頭文件怎么組織好包含關系呢?Eigen給出的答案是,在對外頭文件中按照依賴關系排列頭文件順序。
以Core模塊為例,該模塊定義了Eigen核心數據結構和基本功能。Eigen/src/Matrix.h定義了矩陣,其定義如下:
template<typename Scalar_, int Rows_, int Cols_, int Options_, int MaxRows_, int MaxCols_> class Matrix : public PlainObjectBase<Matrix<Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_> >
但是我們發現,Matrix.h並沒有直接
#include<PlainObjectBase.h>。打開Eigen/Core,我們就可以發現如下結構
當用戶將Eigen/Core包含在自己的文件中,編譯時頭文件的代碼一經展開,PlainObjectBase便是已經聲明並定義好的了,所以客戶端代碼並不會發生鏈接問題。需要注意的是,如果客戶只include其中一個文件比如Matrix.h,此時就會發生鏈接問題,因為找不到PlainObjectBase。這樣做的好處是減少了各文件之間的編譯依賴關系。