ptr作为类成员,移动语义无法用clang编译
我无法获得clang(Apple LLVM 4.2版(clang-425.0.28))来编译这些类:
struct A {
int f(){return 2;}
};
class Cl{
std::unique_ptr<A> ptr;
public:
Cl(){ptr = std::unique_ptr<A>(new A);}
Cl(const Cl& x) : ptr(new A(*x.ptr)) { }
Cl(Cl&& x) : ptr(std::move(x.ptr)) { }
Cl(std::unique_ptr<A> p) : ptr(std::move(p)) { }
void m_ptr(std::unique_ptr<A> p){
ptr = std::unique_ptr<A>(std::move(p));
}
double run(){return ptr->f();}
};
我想按如下方式运行构造函数:
std::unique_ptr<A> ptrB (new A);
Cl C = Cl(ptrB);
但如果我这样做,我得到以下编译器错误:../src/C++11-2.cpp:66:10:错误:调用隐式删除复制构造函数的'std :: unique_ptr'C.m_ptr(的ptrB);
我可以通过运行Cl(std::move(ptrB))
来解决编译器问题,但是这实际上并没有将A的所有权从ptrB移开:我仍然可以运行ptrB->f()
而不会导致运行时崩溃...其次,构造函数不是很令人满意,因为我想在类接口中隐藏std::move
的实现。
提前致谢。
由于ptrB通过值传递给Cl的拷贝构造函数,所以对Cl(ptrB)的调用将尝试创建ptrB的副本,然后调用unique_ptr的(明显禁用的)复制构造函数。 为了避免创建ptrB的额外副本,请执行以下操作:
Cl C = Cl(std::unique_ptr<A>(new A)); //A temporary is created on initialization, no extra copy steps performed
要么:
std::unique_ptr<A> ptrB (new A);
Cl C = Cl(std::move(ptrB)); //Move semantics used. Again, no extra copy steps
或者,在你的拷贝构造函数中使用引用传递(右值或左值):
class Cl{
//...
public:
//...
Cl(std::unique_ptr<A> &p) : ptr(std::move(p)) { }
//...
};
std::unique_ptr<A> ptrB (new A);
Cl C = Cl(ptrB);
PS哦,顺便说一下:对象保持未指定状态,但在std :: move()之后有效 。 我相信这意味着你仍然可以调用ptrB-> f(),并保证返回2 :)
链接地址: http://www.djcxy.com/p/59675.html上一篇: ptr as class member and move semantics fail to compile with clang
下一篇: c++