Почему мне разрешено копировать unique_ptr?
Возможный дубликат:
Возврат unique_ptr из функций
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++ version 4.6.1 20110908 (Red Hat 4.6.1-9)
Ответы
Ответ 1
В операторе return, если вы возвращаете локальную переменную, выражение рассматривается как rvalue и, таким образом, автоматически перемещается. Это похоже на:
return std::move(p);
Он вызывает конструктор unique_ptr(unique_ptr&&)
.
В основной функции bar()
создает временную, которая является rvalue, и также правильно перемещается в p
в main
.
Ответ 2
Скопирован не, он перемещается.
Оператор return эквивалентен этому:
return std::move(p);
Педантично, это семантически эквивалентно. На самом деле компилятор может оптимизировать код, возвращая вызов вызову-конструктору. Но это возможно, только если вы напишете его как:
return p; //It gives the compiler an opportunity to optimize this.
Это рекомендуется. Однако компилятор не имеет возможности оптимизировать, если вы пишете это:
return std::move(p); //No (or less) opportunity to optimize this.
Это не.: -)
Ответ 3
Я думаю, что копирование из lvalue отключено, но "bar()" является rvalue, поэтому он в порядке. Вы определенно должны иметь возможность копировать из rvalues.