unique_ptr作为类成员,移动语义无法使用clang进行编译 [英] unique_ptr as class member and move semantics fail to compile with clang

查看:992
本文介绍了unique_ptr作为类成员,移动语义无法使用clang进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法获得俚语(Apple LLVM版本4.2(clang-425.0.28))来编译这些类:

I can't get clang (Apple LLVM version 4.2 (clang-425.0.28)) to compile these classes:

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();}
};

我想运行构造函数,如下所示:

I would like to run the constructor as follows:

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);

but if I do this I get the following compiler error: ../src/C++11-2.cpp:66:10: error: call to implicitly-deleted copy constructor of 'std::unique_ptr' C.m_ptr(ptrB);

我可以通过运行 Cl(std :: move(ptrB))来解决编译器问题,但是这不会真正移动A的所有权远离ptrB :我仍然可以运行 ptrB-> f(),而不会导致运行时崩溃...第二,构造函数不是很令人满意,因为我想隐藏在类接口中实现 std :: move

I can solve the compiler problem by running Cl(std::move(ptrB)) but this doesn't actually move the ownership of A away from ptrB: I can still run ptrB->f() without causing a run-time crash... Secondly, the constructor is not very satisfying, since I want to hide the implementation of std::move in the class interface.

提前感谢。

推荐答案

由于ptrB通过传递给Cl的复制构造函数,对Cl(ptrB)的调用尝试创建ptrB这又调用了一个(显然禁用)的unique_ptr的复制构造函数。为了避免创建ptrB的额外副本,请执行以下操作:

Since ptrB is passed by value to Cl's copy constructor, a call to Cl(ptrB) tries to create a copy of ptrB which in turn calls a (obviously disabled) copy constructor of unique_ptr. In order to avoid creating an extra copy of ptrB, do the following:

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

或者,在复制构造函数中使用传递引用(rvalue或lvalue) :

Or, use pass by reference (rvalue or lvalue) in your copy constructor:

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:)

P.S Oh and by the way: the objects stay in unspecified, but valid state after std::move(). I believe that means you can still call ptrB->f(), and it is guaranteed to return 2 :)

这篇关于unique_ptr作为类成员,移动语义无法使用clang进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆