2017-05-25 22 views
3

我有一個類,它包含一個用unique_ptr管理的c-style數組。我想提供一個構造函數:設置類成員unique_ptr <T[]>數組而不復制

class A { 
    unique_ptr<T[]> p; 
public: 
    A(int d, X x) : p(new T[d]) { 
    //Transfer from x to p without copying 
    } 
} 

這樣我就可以建立我的對象的東西,如:

int main(..) { 
    A a{n,{expr1,expr2,..}}; 
} 

其中{表達式1,表達式2,...}包含的值(在運行時進行評估)爲初始化。由於這個列表是暫時的,在我看來浪費資源來構建它,將它的值複製到實際的對象中並丟棄它。我相信通過移動semantincs,rvalues和C++ 11的所有漂亮功能,應該爲這個簡單的任務提供一個解決方案,但是我找不到它(我在C++中很新穎)。

我想堅持使用c風格的數組,不要移動到std :: vectors。有解決方案嗎?

+0

你說的 「不復制」 是什麼意思?您希望堆分配使用數據成員進行初始化? – Justin

+0

*「我想堅持使用c風格的數組,並且不要移動到std :: vectors」* [原文如此]爲什麼您不想使用該語言庫提供的功能?不這樣做就是所謂的重新發明輪子。 –

+0

@舊版代碼,僅舉幾例。 – 2017-05-25 21:05:39

回答

2

是的,你可以用完美轉發:

#include <memory> 
#include <string> 

struct S 
{ 
    S(int) {} 
    S(S const&) = delete; 
    S(S&&) = default; 
}; 

template<typename T> 
struct A 
{ 
    std::unique_ptr<T[]> p; 

    template<typename... Args> 
    A(int d, Args&&... args) 
     : p(new T[sizeof...(args)]{std::forward<Args>(args)...}) 
    { 
    } 
}; 

int main() 
{ 
    A<int> a(0, 1, 2, 3, 4); 

    A<std::string> b(0, "hello", "world!", "\n"); 

    S s(0); 
    A<S> c(0, std::move(s), 2, 3); 
} 
2

我想在這裏做兩點。

  1. AFAICS,std::unique_ptr<T[]>提供你在標準C很少的益處++使用std::vector<T>,即減小的存儲器佔用(64,而不是128個字節用於容器本身在64位機器上並且還可能量的溶液使用的堆),但請參閱here的討論。任何C++的newby應該堅持std::vector

  2. 移動語義僅對管理堆上內存的對象('自由存儲')有用。所以只有當你的expr1expr2等都是自己跟蹤分配內存的對象時,移動纔有意義。這裏沒有出現這種情況,所以只需複製。

+0

Re。 2,'T'可能是'std :: string'或者更多的相關類 –

+0

@Walter我不完全理解你的第二個評論。也許我弄錯了一切,但我可​​以想象有人在堆棧上構建一個臨時對象,而不是將該對象作爲類的數據成員「移動」。 – Teloze

+1

@ user8066678你似乎還沒有理解移動的想法。如果您在堆棧上創建臨時對象,則無法移動它。移動意味着:將指針複製到堆上的對象(而不是複製對象本身),但確保將從中複製的指針變量重置爲空。它與其他被稱爲「淺拷貝」的東西類似(例如,G。在Python中)。 – Walter

相關問題