考慮以下函式Foo:
// ...
Eigen::Vector3d Foo() {
Eigen::Vector3d res;
// ...
return res;
}
int main () {
Eigen::VectorXd foo = Foo(); // (1)
return 0;
}
(1)由于回傳值優化,該行不應創建任何臨時物件。但請考慮以下情況:
// ...
int main () {
Eigen::VectorXd foo;
// ...
foo.head<3>() = Foo(); // (2)
return 0;
}
是否(2)創建任何臨時物件?更一般地說,是否像在(2)創建任何臨時物件那樣初始化矩陣的任何塊?如果不是這種情況,那就太好了。否則,我可以重新定義Foo如下:
// ...
void AlternativeFoo(Eigen::Ref<Eigen::Vector3d> res) {
// Modify res
}
int main () {
Eigen::VectorXd foo;
// ...
AlternativeFoo(foo.head<3>()); // (3)
return 0;
}
是(3)在不創建臨時檔案的情況下實作上述目標的唯一方法嗎?
uj5u.com熱心網友回復:
由于回傳值優化,第 (1) 行不應創建任何臨時檔案。
不,它必須為 的回傳值實作一個臨時的Foo。
的回傳型別Foo和變數的型別foo不匹配(最多 cv 限定):Vector3dvs VectorXd.
但這是允許復制省略的必要條件。如果不是這種情況,首先使用的建構式既不是復制建構式也不是移動建構式。
所以省略不會發生,在將要呼叫的建構式中, 的回傳值Foo系結到一個參考引數,這將導致臨時的物化。
(2) 是否創建任何臨時物件?更一般地說,在 (2) 中初始化矩陣的任何塊是否會創建任何臨時變數?
是的,Foo回傳值的臨時物件將再次被物化,這次是由于系結到operator=.
(3)是在不創建臨時檔案的情況下實作上述目標的唯一方法嗎?
我會假設是這樣,但無論如何這可能無關緊要。假設Foo可以行內,這種區別很可能變得毫無意義,編譯器會弄清楚是否Foo可以直接在存盤上執行in 的操作foo。
如果Foo不能行內,那么復制向量的三個條目不太可能與函式呼叫有重大關聯。在這種情況下,您的替代解決方案會強制進行額外的間接訪問,這可能比復制一些值的成本更高。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/388763.html
上一篇:基類是派生類的歧義基類
下一篇:我必須在C 中定義默認建構式嗎?
