I was updating some old code that uses auto_ptr to use unique_ptr instead. It was mostly a search and replace job, but I found I was getting a compilation error in one place where the code returns a unique_ptr.
Here is an example that illustrates the issue:
#include <string>
#include <iostream>
#include <memory>
#include <utility>
using namespace std;
struct Foo {
    unique_ptr<string> us;
    Foo() {
        this->us = unique_ptr<string>(new string("hello"));
    }
    unique_ptr<string> bar() {
        return this->us;
    }
};
int main(int argc, const char **argv) {
    Foo foo;
    unique_ptr<string> s = foo.bar();
    cout << *s << endl;
}
When I compile that, I get this:
t1.cpp: In member function ‘std::unique_ptr<std::basic_string<char> > Foo::bar()’:
t1.cpp:17:16: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = std::basic_string<char>; _Dp = std::default_delete<std::basic_string<char> >]’
   return this->us;
                ^~
In file included from /opt/rh/devtoolset-7/root/usr/include/c++/7/memory:80:0,
                 from t1.cpp:4:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/unique_ptr.h:388:7: note: declared here
       unique_ptr(const unique_ptr&) = delete;
       ^~~~~~~~~~
If I alter the line with the error to specify a move like this:
        return move(this->us);
then it works.
I have found multiple references indicating that a move should not be required - for example this SO question, and these guidelines from the chromium project.
My question is: why does the move need to be explicitly specified in this case? Is it related to fact that I am returning the value of an instance variable somehow?
Apologies in advance if this is a dupe - I feel sure it would have been asked before, but I struggle to come up with search terms that find it.
 
     
     
     
     
    