2010-09-21 114 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