移动涉及const unique_ptr的构造函数

Agr*_*hak 4 c++ const move unique-ptr move-constructor

在下面的代码中,我创建了p const,因为在Foo的生命周期中它永远不会指向任何其他int.这不会编译,因为调用了unique_ptr的复制构造函数,这显然已被删除.除了使p非常数之外还有其他解决方案吗?谢谢.

#include <memory>

using namespace std;

class Foo 
{
public:
  //x is a large struct in reality
  Foo(const int* const x) : p(x) {};
  Foo(Foo&& foo) : p(std::move(foo.p)) {};
private:
  const unique_ptr<int> p;
};
Run Code Online (Sandbox Code Playgroud)

Per*_*xty 6

移动构造函数的语义是矛盾的.

您声明了一个const std::unique_ptr(唯一)拥有它初始化的值. 但是你已经声明了一个移动构造函数,它应该在构造时将该值移动到另一个对象中.

那么你认为应该std::unique_ptr在"临时"移动构造中发生什么呢?

如果你想要它,release()你就违反了它的要求const.如果你希望它保留它的值,你就违反了std::uniquewith 的约束,只需要一个这样的对象来拥有任何给定的对象. 将军.

这个问题揭示了C++语言的一个微妙限制.它需要move语义离开复制到从为有效的对象.

对于"破坏性移动"有几个非常合理的建议,这些建议实际上更好地反映了大多数用途move正在做什么 - 从那里获取价值'使'无效'.

谷歌他们.我没有做过文献调查,所以不想推荐一个.

你在这里的替代方案是删除const或投射它.我强烈建议删除它.您可以确保您的类的语义确保适当的常量,没有任何影响,也没有'丑陋的可疑' const_cast.

#include <iostream>
#include <memory>

class Foo 
{
public:
  Foo(const int x) : p(new int(x)) {};
  Foo(Foo&& foo) :
    p(std::move(foo.p)) {

    };

    int get(void)const{
        return *(this->p);
    }

private:
     std::unique_ptr<int> p;
};

Foo getMove(){
    return Foo(88);
}

int main(){

    Foo bar(getMove());    
    std::cout<<bar.get()<<std::endl;

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)