2011-08-24 83 views
1

功能可以說我有以下簡單的Vector類:「雙師型」 與的C++ 0x

template <class N> 
class Vector<N> 
{ 
public: 
    std::array<int, N> a; 
}; 

我在double第一次嘗試如下:

template <class N> 
Vector<N>&& double1(Vector<N>&& x) 
{ 
    for (int i = 0; i != N, ++i) { x.a[i] *= 2; } 
    return static_cast<Vector<N>&&>(x); 
} 

這看起來確定最初,但如果我這樣做:

auto x&& = double1(makeVector(1,2,3)) 

我不得不臨時問題的引用。

我的第二次嘗試以下操作:

template <class N> 
Vector<N> double2(Vector<N>&& x) 
{ 
    for (int i = 0; i != N, ++i) { x.a[i] *= 2; } 
    return x; 
} 

這似乎沒有上面提到暫時性的問題,但確實我認爲是多此一舉/複製的回報。

我可以同時避免參照臨時問題,並通過做額外的移動/複製以下:

template <class N> 
void double3(Vector<N>& x) 
{ 
    for (int i = 0; i != N, ++i) { x.a[i] *= 2; } 
} 

但後來我不得不做出改變的說法,我認爲這是一個有點亂。我還必須給臨時名稱命名。

我最終的想法是以下幾點:

template <class N> 
Vector<N> double4(Vector<N> x) 
{ 
    for (int i = 0; i != N, ++i) { x.a[i] *= 2; } 
    return x; 
} 

,它能夠避免所有副本,如果參數存儲在同一個地方的結果,但我不知道如何做到這一點。

基本上我正在尋找具有以下特性的雙重功能:

(1)當自動分配給臨時問題無法引用。 (2)臨時通過時沒有副本。 (3)傳遞非臨時性時不修改參數。

任何人都有任何想法如何把這三樣東西放在一起?

編輯

也許把事情更簡單地說,這就是我想要的行爲。

(1)如果參數是臨時參數,則將其修改到位。
(2)否則,複製一份。

+0

我懷疑這是可能的。您不能在臨時通過時不進行復制,仍然使用結果。你也不能讓它在通過非臨時性時不修改參數,也不能使其成爲副本。 –

+3

不要編寫返回右值引用的函數。一個普通的舊參考有什麼問題?爲什麼在第一次嘗試時,你實際上已經準備好「移動」你的論點,然後將它重新分配給另一個變量,那麼改變論證「混亂」? –

+1

另外,這裏的任何一點是什麼,你的類不包含任何類型的資源處理程序,甚至可以從移動語義中受益。 –

回答

2

你最終的想法是正確的,有效的,用它去:

template <class N> 
Vector<N> double4(Vector<N> x) 
{ 
    for (int i = 0; i != N, ++i) { x[i] *= 2; } 
    return x; 
} 
+0

我不會那麼高效。或者更正,因爲'std :: array'有_two_模板參數,而不是一個。所以'Vector '沒有意義。而且你似乎在不必要地進行大量的複製,因爲'std :: array's的數據不能被移動。 –

+0

@Nicol:有多少模板參數'std :: array <>'沒有關係 - 'Vector <>'的聲明只有一個模板參數。就不必要的拷貝而言,這個答案在general_中是正確的,如果不是'std :: array <>'的話。 – ildjarn

+0

@Nicol:只有一個對拷貝構造函數的調用(除非編譯器太愚蠢,無法在函數返回的地方構造'x')。這是多麼不必要的複製? – leftaroundabout

1

這個代碼是沒有意義的。

首先,std :: array需要兩個模板參數:一個類型和一個大小。其次,std :: array是一個聚合;它不是真正可移動的。內容可以移動,但不能移動對象本身。

第三,你濫用r值參考沒有明顯的收益。如果你想加倍的話,就像使用C++ 0x之前那樣使用常規引用。

但是後來我必須對參數進行修改,我認爲這有點麻煩。我還必須給臨時名稱命名。

實際存儲對象沒有什麼不對。並非所有事情都需要暫時的。如果沒有其他原因,而不是C++不允許的話,嘗試通過一個函數調用來臨時推送,你會獲得絕對的效率。

關於改變參數沒有什麼「雜亂」的; C++不是一種功能語言。

哦,並且r值引用不是「引用臨時對象」。他們可以參考臨時,但這不是他們唯一的事情。