gpt4 book ai didi

c++ - 移动后通过右值引用返回

转载 作者:搜寻专家 更新时间:2023-10-31 00:53:40 24 4
gpt4 key购买 nike

我对下面的例子有几个问题:

unique_ptr<A> foo(){
unique_ptr<A> a = make_unique<A>(5);
return move(a);
}

unique_ptr<A>&& foo(){
unique_ptr<A> a = make_unique<A>(5);
return move(a);
}

unique_ptr<int> foo(){
unique_ptr<int> a = make_unique<int>(5);
return a;
}

第一个例子:

为什么编译器允许这样的事情?我们不是返回一个右值引用吗?为什么编译器允许这样的隐式转换?谁持有底层对象?最后谁负责销毁它?

第二个例子:

当我这样做时,我从函数的返回类型中得到了垃圾。虽然我认为这是执行此操作的“正确”方法,但我们不是在声明我们正在返回一个 rval ref,并且实际上是这样移动我们的对象吗?

第三个例子:

如果一个unique_ptr的复制构造函数被删除,这里会发生什么允许这个函数? a 是一个 unique_ptr,我们按值返回它,这样不会创建一个拷贝吗?

最佳答案

这是一个快速的总结:

  1. 第一个例子还可以,但是 std::move(a)抑制 cooy-elision。当然,移动比复制更好,但还没有更好的作品。

  2. 右值引用仍然是引用,您需要保持被引用对象的事件。在可以访问返回的引用之前,被引用的本地对象被销毁。尽管一些标准函数会返回右值引用(std::move(x)std::forward<T>(x)std::declval<T>()),但返回右值引用很少有用,但对于这些函数,会返回一个非本地对象。

  3. 当复制省略成为可能时,对象被隐式移动。这就是复制省略仍然可行的方法。

您似乎没有意识到复制省略:在某些需要复制的情况下,即使程序的语义已更改(即副作用copy ctor 和 dtor 不会发生)。实际上,复制省略允许立即在正确的位置构造对象。只有少数情况允许复制省略(具体规则更复杂):

  1. 复制临时对象时。
  2. 返回局部变量时。
  3. 当抛出局部变量时。
  4. 重新抛出捕获的对象时。

由于在这些情况下没有进行复制,因为对象已经在正确的位置,因此将规则扩展到移动操作似乎是合理的:当允许复制省略时,对象被隐式移动。最终效果是拥有复制或移动构造函数就足够了。任何体面的编译器既不会复制也不会移动,但会省略复制/移动构造。

关于c++ - 移动后通过右值引用返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47964301/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com