20.7.1.2 [unique.ptr.single]定义了这样的复制构造函数:
// disable copy from lvalue
unique_ptr(const unique_ptr&) = delete;
unique_ptr& operator=(const unique_ptr&) = delete;
那么,为什么以下代码编译得很好?
#include <memory>
#include <iostream>
std::unique_ptr< int > bar()
{
std::unique_ptr< int > p( new int(4));
return p;
}
int main()
{
auto p = bar();
std::cout<<*p<<std::endl;
}
我这样编译:
g++ -O3 -Wall -Wextra -pedantic -std=c++0x kel.cpp
编译器:g ++版本4.6.1 20110908(Red Hat 4.6.1-9)
答案 0 :(得分:43)
在return语句中,如果返回局部变量,则表达式将被视为右值,因此会自动移动。因此类似于:
return std::move(p);
它调用unique_ptr(unique_ptr&&)
构造函数。
在主要功能中,bar()
会产生一个临时值,这是一个右值,并且也会正确移动到p
中的main
。
答案 1 :(得分:16)
不 已复制,已移动。
return语句等同于:
return std::move(p);
迂腐地说,这是语义等价的。实际上,编译器可以优化代码,从而忽略对move-constructor的调用。但只有当你把它写成:
时才有可能return p; //It gives the compiler an opportunity to optimize this.
这是推荐的。但是,如果您编写此代码,编译器将无法进行优化:
return std::move(p); //No (or less) opportunity to optimize this.
建议不。 : - )
答案 2 :(得分:1)
我认为从左值复制是禁用的,但是“bar()”是一个右值,所以没关系。你肯定需要能够从rvalues复制。