title: invalid initialization of non-const reference of type from an rvalue of type
body: <p>I am writing some code based on issue 28 smart pointer of more effective c++ as follows. However, it cannot compile:</p>
  
  <pre><code>main.cpp: In instantiation of 'SmartPointer&lt;T&gt;::operator SmartPointer&lt;U&gt;() [with U = MusicProduct; T = Cassette]':
  main.cpp:99:17:   required from here
  main.cpp:48:39: error: invalid initialization of non-const reference of type 'SmartPointer&lt;MusicProduct&gt;&amp;' from an rvalue of type 'SmartPointer&lt;MusicProduct&gt;'
         return SmartPointer&lt;U&gt; (ptr_);
                                     ^
  main.cpp:16:9: note:   initializing argument 1 of 'SmartPointer&lt;T&gt;::SmartPointer(SmartPointer&lt;T&gt;&amp;) [with T = MusicProduct]'
       SmartPointer(SmartPointer&lt;T&gt;&amp; other)
       ^
  </code></pre>
  
  <p>Either of these two changes works: </p>
  
  <ol>
  <li><p>in the implementation of operator SmartPointer (), create an object and return:</p>
  
  <p>SmartPointer a(ptr_);</p>
  
  <p>return a;</p></li>
  <li><p>Or, make the parameter of the copy constructor as const</p>
  
  <p>SmartPointer(const SmartPointer&amp; other)</p>
  
  <p>and comment the line</p>
  
  <p>other.ptr_ = nullptr;</p></li>
  </ol>
  
  <p>Is there any reason why either of the solutions works? Thanks.</p>
  
  <hr>
  
  <pre><code>#include &lt;iostream&gt;
  
  template &lt;typename T&gt;
  class SmartPointer
  {
    public:
      SmartPointer(T* ptr) : ptr_(ptr) {}
      ~SmartPointer()
      {
        if (ptr_)
        {
          delete ptr_;
        }
      }
  
      SmartPointer(SmartPointer&lt;T&gt;&amp; other)
      {
        ptr_ = other.ptr_;
        other.ptr_ = nullptr;
      }
  
      SmartPointer&lt;T&gt;&amp; operator = (SmartPointer&lt;T&gt;&amp; other)
      {
        if (this == &amp;other)
        {
          return *this;
        }
  
        if (ptr_)
        {
          delete ptr_;
        }
  
        ptr_ = other.ptr_;
        other.ptr_ = nullptr;
  
        return *this;
      }
  
      template &lt;typename U&gt;
      operator SmartPointer&lt;U&gt; ()
      {
        // it works
        //SmartPointer&lt;U&gt; a(ptr_);
        //return a;
  
        // error
        return SmartPointer&lt;U&gt; (ptr_);
      }
  
      T&amp; operator * () const
      {
        return *ptr_;
      }
  
      T* operator -&gt; () const
      {
        return ptr_;
      }
  
    private:
      T* ptr_ = nullptr;
  };
  
  class MusicProduct
  {
  public:
    MusicProduct(const std::string&amp; name) : name_(name) {}
    virtual ~MusicProduct() {}
  
    virtual void Play() const = 0;
    virtual void ShowName() const
    {
      std::cout &lt;&lt; name_ &lt;&lt; std::endl;
    }
  
  private:
    std::string name_;
  };
  class Cassette : public MusicProduct
  {
    public:
    Cassette(const std::string&amp; name) : MusicProduct(name) {}
    void Play () const
    {
      std::cout &lt;&lt; "play cassette" &lt;&lt; std::endl;
    }
  };
  
  void CallPlay(const SmartPointer&lt;MusicProduct&gt;&amp; sp)
  {
    sp-&gt;Play();
  }
  
  int main()
  {
    SmartPointer&lt;Cassette&gt; a(new Cassette("Zhang"));
    a-&gt;ShowName();
    CallPlay(a);
    return 0;
  }
  </code></pre>