«Использование удаленной функции» при вызове `std :: unique_ptr` конструктора перемещения? - PullRequest
2 голосов
/ 02 мая 2020

Я сталкиваюсь с проблемой компиляции при определении функции, которая принимает ссылку на перемещение для объекта std::unique_ptr.

#include <memory>

class foo {
 public:
    foo() { /* */ };
};

void function(foo&& arg) {
    foo bar(arg);
}

void function2(std::unique_ptr<foo>&& arg){
    std::unique_ptr<foo> foo(arg);
}


int main(int argc, char const *argv[]) {
    foo A;
    function(foo());
    function2(std::unique_ptr<foo>(new foo));
    return 0;
}

, что приводит к:

test.cpp: In function ‘void function2(std::unique_ptr<foo>&&)’:
test.cpp:16:30: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = foo; _Dp = std::default_delete<foo>]’
   16 |  std::unique_ptr<foo> foo(arg);
      |                              ^
In file included from /usr/include/c++/9.3.0/memory:80,
                 from test.cpp:1:
/usr/include/c++/9.3.0/bits/unique_ptr.h:414:7: note: declared here
  414 |       unique_ptr(const unique_ptr&) = delete;

Я попытался скопировать его, передав ссылку на пользовательский класс, но, как и ожидалось, он не вызывает проблем в качестве конструктора перемещения по умолчанию неявно объявлено компилятором. Почему это происходит тогда с std::unique_ptr? Для std::unique_ptr есть конструктор перемещения по умолчанию, так чего мне не хватает?

1 Ответ

3 голосов
/ 02 мая 2020

Из соображений безопасности налагаются некоторые ограничения. Именованная переменная никогда не будет считаться значением, даже если она объявлена ​​как таковая. Для получения значения r следует использовать шаблон функции std::move(). Rvalue ссылки также могут быть изменены только при определенных обстоятельствах, так как предназначены для использования в основном с конструкторами перемещения.

void function2(std::unique_ptr<foo>&& arg) {
    std::unique_ptr<foo> foo(std::move(arg));
}
...