2010-09-21 169 views
4

我試圖使用從C++ X0的的unique_ptr的,通過做C++ X0的unique_ptr GCC 4.4.4

#include <memory> 

與-std =的C++ 0x作曲,但它是這是一個例子,拋出許多錯誤。

/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = Descriptor, _Tp_Deleter = std::default_delete<Descriptor>]’ 

UPDATE **** 這就是我要做的,我已刪除的typedef,所以你可以清楚地看到該類型

static std::unique_ptr<SomeType> GetSomeType() 
{ 
    std::unique_ptr<SomeType> st("Data","Data2",false); 

    std::unique_ptr<OtherType> ot("uniportantconstructor data"); 

    st->Add(ot); 

    return st; 

} 

//Public method of SomeType 
    void Add(std::unique_ptr<OtherType> ot) 
    { 
    //otmap is std::map<std::string,std::unique_ptr<OtherType> > 
    //mappair is std::Pair<std::string,std::unique_ptr<OtherType> > 
    otMap.Insert(mappair(ot->name(),ot)); 
    } 

UPDATE:

如果我的課堂SOMETYPE有一個方法可以從地圖返回一個元素(使用鍵)說

std::unique_ptr<OtherType> get_othertype(std::string name) 
{ 
    return otMap.find(name); 
} 

那將確保調用者會收到一個指向地圖中的指針而不是副本?

+0

我很確定'unique_ptr'沒有'Add'方法。你的意思是'ST->添加'任何機會? – fredoverflow 2010-09-22 10:21:23

+0

是的,我修好了,抱歉,從內存中鍵入它沒有編譯它或任何東西。 – Mark 2010-09-22 10:34:57

回答

4
std::unique_ptr<OtherType> ot("unimportant constructor data"); 
st->Add(ot); 

您可以在左值不能傳遞給接受unique_pointer的功能,因爲unique_pointer沒有拷貝構造函數。您必須移到左值(它轉換爲一個x值),或通過prvalue:

// pass an xvalue: 
std::unique_ptr<OtherType> ot("unimportant constructor data"); 
st->Add(std::move(ot)); 
// note: ot is now empty 

// pass a prvalue: 
st->Add(std::unique_ptr<OtherType>("unimportant constructor data")); 

裏面Add方法,事情有點複雜。首先,你必須從ot,因爲形式參數總是左值(因爲他們有名字)。其次,您不能從ot移動並獲得ot->name()作爲mappair函數的參數,因爲參數評估的順序在C++中未指定。因此,我們必須得到ot->name()在一個單獨的語句從ot移動前:

void Add(std::unique_ptr<OtherType> ot) 
{ 
    auto name = ot->name(); 
    otMap.Insert(mappair(name, std::move(ot))); 
} 

希望這有助於。請注意,在沒有(理智的)情況下,兩個對象可以指向相同的東西。如果你需要這個功能,unique_ptr不是你想要的。

+0

真棒,這正是我一直在尋找的,謝謝。 – Mark 2010-09-22 10:37:05

+0

不要忘記包含''來獲得'std :: move' – sellibitze 2010-09-22 17:22:38

4

它看起來像你試圖使用複製構造函數。沒有一個。如果你調用的代碼如下所示:

T *ptr = /* whatever */; 
std::unique_ptr<T> up = ptr; 

您必須更改第二行這樣的:

std::unique_ptr<T> up (ptr); 

的原文(基本上)隱含轉動分配到:

std::unique_ptr<T> up (std::unique_ptr<T>(ptr)); 

複製構造函數已被刪除。 「已刪除的函數」是C++ 0x表示用於顯式刪除隱式特殊成員函數。在這種情況下,複製構造函數。

+0

謝謝,對錯誤的解釋應該有助於未來。 – Mark 2010-09-21 19:36:59

+0

這是否意味着我不能通過unique_ptr作爲參數或從函數返回它? – Mark 2010-09-21 19:41:18

+0

@Mark:不,對兩者都是。但是你必須使用移動構造函數,而不是複製構造函數。例如,'函數(std :: move(pointer));' – 2010-09-21 19:45:33

1

正如@Steve說你可能使用拷貝構造函數,unique_ptr不支持複製語義,如果你想移動重視到另一個unique_ptr你必須move它。

unique_ptr<T> other = std::move(orig); // orig is now null