在下面的代码中,我将 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;
};
最佳答案
你的 move 构造函数的语义是矛盾的。
你已经声明了一个 const std::unique_ptr
,它将(唯一地)拥有它被初始化的值。
但是您已经声明了一个 move 构造函数,它应该在构造时将该值 move 到另一个对象中。
那么,您认为从 move 构造的“临时”中的 std::unique_ptr
应该发生什么?
如果您希望它被release()
ed,您就违反了它的const
性。
如果你想让它保留它的值(value),你就违反了 std::unique
的约束,它要求不超过一个这样的对象来拥有任何给定的对象。
将死。
这个问题揭示了 C++ 语言的一个微妙限制。它需要 move
语义来将复制到 and from 作为有效对象。
“破坏性 move ”有几个非常合理的建议,它们实际上可以更好地反射(reflect) move
的大多数用途正在做的事情——从那里取一个值到这里“使那里的东西无效”。
谷歌他们。我没有做过文献调查,所以不想推荐。
您在这里的替代方法是删除 const
或强制转换它。
我强烈建议删除它。您可以确保您的类的语义确保适当的 const-ness,而不会产生影响,也不会出现“丑陋的嫌疑人”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;
}
关于c++ - 涉及 const unique_ptr 的 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29194304/