从函数返回unique_ptr [英] Returning unique_ptr from functions

查看:674
本文介绍了从函数返回unique_ptr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

unique_ptr< T> 不允许复制构造,而是支持移动语义。然而,我可以从函数中返回 unique_ptr< T> ,并将返回的值赋给变量。

unique_ptr<T> does not allow copy construction, instead it supports move semantics. Yet, I can return a unique_ptr<T> from a function and assign the returned value to a variable.

#include <iostream>
#include <memory>

using namespace std;

unique_ptr<int> foo()
{
  unique_ptr<int> p( new int(10) );

  return p;                   // 1
  //return move( p );         // 2
}

int main()
{
  unique_ptr<int> p = foo();

  cout << *p << endl;
  return 0;
}

上面的代码编译并按预期工作。那么如何行 1 不调用复制构造函数并导致编译器错误?如果我不得不使用 2 代替它是有意义的(使用 2

The code above compiles and works as intended. So how is it that line 1 doesn't invoke the copy constructor and result in compiler errors? If I had to use line 2 instead it'd make sense (using line 2 works as well, but we're not required to do so).

我知道C ++ 0x允许这个异常 unique_ptr value是一个临时对象,只要函数退出就会被销毁,从而保证返回的指针的唯一性。我很好奇这是如何实现的,是特殊的情况下在编译器还是在语言规范中有一些其他子句,这是利用?

I know C++0x allows this exception to unique_ptr since the return value is a temporary object that will be destroyed as soon as the function exits, thus guaranteeing the uniqueness of the returned pointer. I'm curious about how this is implemented, is it special cased in the compiler or is there some other clause in the language specification that this exploits?

推荐答案


在语言规范中是否还有其他子句可供使用?

is there some other clause in the language specification that this exploits?

是,见12.8§34和§35:

Yes, see 12.8 §34 and §35:


当满足某些标准时,允许实现省略复制/类对象[...]
允许复制/移动操作的调用,称为复制elision [...]
在函数的返回语句中,类返回类型,当表达式是名称
a非易失性自动对象
具有相同的cv非限定类型作为函数返回类型[...]

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object [...] This elision of copy/move operations, called copy elision, is permitted [...] in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object with the same cv-unqualified type as the function return type [...]

当满足复制操作的限制条件并且要复制的对象由lvalue指定时,首先执行
重载分辨率来选择复制的构造函数

When the criteria for elision of a copy operation are met and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.






只是想要添加一点,返回值应该是默认选择在这里,因为在最坏的情况下,在return语句中的命名值,即在C ++ 11,C ++ 14和C ++ 17中没有elisions被视为一个右值。例如,以下函数使用 -fno-elide-constructors 标志编译

std::unique_ptr<int> get_unique() {
  auto ptr = std::unique_ptr<int>{new int{2}}; // <- 1
  return ptr; // <- 2, moved into the to be returned unique_ptr
}

...

auto int_uptr = get_unique(); // <- 3

在编译时设置标志有两个移动(1和2)发生在这个功能,然后一个移动(3)。

With the flag set on compilation there are two moves (1 and 2) happening in this function and then one move later on (3).

这篇关于从函数返回unique_ptr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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