2016-12-13 13 views
0

我仍然不確定何時返回值是C++中的一個好主意,如果不是。在以下情況下,可以嗎?何時按值返回好嗎?

vector<int> to_vec(const Eigen::MatrixXi& in){ 
    vector<int> out; 
    // copy contents of in into out 
    return out; 
} 

Eigen::MatrixXi to_eigen(const vector<int>& in){ 
    Eigen::MatrixXi out; 
    // copy contents of in into out 
    return out 
} 

根據這些對象vectorMatrixXi是如何工作的,它可能會導致昂貴的拷貝。另一方面,我假設他們利用C++的移動功能通過重新使用基礎數據以低成本複製。

不知道確切的實施,我能承擔?

+0

搜索「複製省略」和「返回值優化」。 [在本徵移動語義]的 – molbdnilo

+1

可能的複製(http://stackoverflow.com/questions/26959846/move-semantics-in-eigen) –

+0

何不到載體中的引用傳遞爲函數來填充? – Rhett

回答

3

在這種情況下,你聲明一個局部變量,初始化它並按值返回它,假設你的編譯器將elide拷貝,你可以很安全。

這種情況被稱爲命名返回值優化。本質上,不是在函數調用中分配返回值,而是在調用站點完成並作爲參考傳入。按值返回是最好的選擇,因爲你不需要在呼叫站點聲明一個變量來通過,但性能將會如你所願。

在C++ 17,copy elision will be mandatory在涉及prvalues(例如T t = get_t();return get_t())大多數情況下,但仍然是可選的NRVO。

+0

小心解釋downvote? – TartanLlama

+1

AKA「編寫正確的邏輯 - 讓編譯器優化它」 –

2

關於使用C的返回值的拇指規則++是:

  1. 從未返回引用一個局部變量
  2. 從來沒有返回一個指針到一個局部變量
  3. 沒有返回名爲值使用移動語義

至於(3) - 這是C++的一個已知問題 - 我們都知道,當一個對象按值返回時,它會激活複製構造函數。這是理論上真正,但實際上錯誤。開啓優化時,編譯器將在對象上使用複製elision

copy elision是一種優化技術,它使得值在調用者範圍內而不是在被調用者範圍內創建,從而防止了昂貴的副本。對該對象的修改將發生在被調用者範圍內。

爲(1)和(2)中,也有關於協同程序和生成一個角落的情況下,但除非你知道你在與他們打交道,(1)和(2)始終有效。

+0

#3很古怪。 'return std :: vector ();'使用移動語義。 –