這是比這更復雜。如果我們在談論任何對象,@Anycorn是正確的,因爲未經優化的版本會在返回時在函數中創建對象的深層副本。然而,隨着優化啓用copyelision允許編譯器來構建返回的對象到位。這不是特定於Eigen的。作爲一個例子,我們可以看一個類似於你的函數返回一個Eigen對象。在調試
Eigen::MatrixXd retMat()
{
Eigen::MatrixXd inMat = Eigen::MatrixXd::Random(1000,1000);
std::cout << &inMat << "\t" << inMat.data() << "\t" << *(inMat.data() + rand() * 20) << "\n";
return inMat;
}
Eigen::SparseMatrix<double> retSMat()
{
Eigen::MatrixXd denseMat = Eigen::MatrixXd::Random(100,100);
Eigen::SparseMatrix<double> inMat = denseMat.sparseView();
std::cout << &inMat << "\t" << "\n";
return inMat;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
Eigen::MatrixXd outMat(5,5);
std::cout << "Dense matrix addresses (1):\n";
std::cout << &outMat << "\t" << outMat.data() << "\n";
outMat = retMat();
std::cout << &outMat << "\t" << outMat.data() << "\n\n";
std::cout << "Dense matrix addresses (2):\n";
Eigen::MatrixXd outMat2 = retMat();
std::cout << &outMat2 << "\t" << outMat2.data() << "\n\n";
std::cout << "Sparse matrix addresses:\n";
Eigen::SparseMatrix<double> outMatSp = retSMat();
std::cout << &outMatSp << "\n";
return 0;
}
運行(優化關閉),我們得到:
Dense matrix addresses (1):
00000032B6A8EF58 00000032B6BDB870
00000032B6A8EEA8 00000032B6CDA070 -0.620289
00000032B6A8EF58 00000032B6CDD070
Dense matrix addresses (2):
00000032B6A8EEA8 00000032B7481070 0.157872
00000032B6A8EF88 00000032B7C3F070
Sparse matrix addresses:
00000032B6A8EE60
00000032B6A8EFC0
我們看到,沒有一個地址是相同的,如將由代碼的天真解釋可以預期的。如果優化被接通時,圖像有一點不同:
Dense matrix addresses (1):
0000009BEB0AF700 0000009BEB14BBF0
0000009BEB0AF780 0000009BEB2C1040 0.862606
0000009BEB0AF700 0000009BEBA7B040
Dense matrix addresses (2):
0000009BEB0AF718 0000009BEB2CC040 -0.601367
0000009BEB0AF718 0000009BEB2CC040
Sparse matrix addresses:
0000009BEB0AF740
0000009BEB0AF740
我們看到,在情況(2)和所述稀疏矩陣實施例中,對象的地址是相同的,這表明該對象在所創建的目標對象地址。請注意,這是比move semantics不同,這需要一個書面move constructor(我敢肯定徵還沒有一個實施的一個)。
關於Eigen,由於它的lazy evaluation,有些表達式立即是not evaluated,但是當它被認爲是謹慎/必要時。在這個簡單的例子中情況並非如此,但如果例子中有一些計算的話。在這樣的情況下,返回的對象威力是被所附的表達式樹/中生成的對象進行評估。
在第一段,不,你不要返回局部變量。你返回* deep *局部變量的副本 - 意味着它們是具有相同初始內容的不同向量。 – Anycorn