title: C++ type erasure with template copy and move constructor
body: <p>I recently started learning about type erasures. It turned out that this technique can greatly simplify my life. Thus I tried to implement this pattern. However, I experience some problems with the copy- and move-constructor of the type erasure class.
  Now, lets first have a look on the code, which is quite straight forward</p>
  
  <pre><code>#include&lt;iostream&gt;
  class A //first class
  {
      private:
          double _value;
      public:
          //default constructor
          A():_value(0) {}
          //constructor
          A(double v):_value(v) {}
          //copy constructor
          A(const A &amp;o):_value(o._value) {}
          //move constructor
          A(A &amp;&amp;o):_value(o._value) { o._value = 0; }
  
          double value() const { return _value; }
  };
  
  class B //second class
  {
      private:
          int _value;
      public:
          //default constructor
          B():_value(0) {}
          //constructor
          B(int v):_value(v) {}
          //copy constructor
          B(const B &amp;o):_value(o._value) {}
          //move constructor
          B(B &amp;&amp;o):_value(o._value) { o._value = 0; }
  
          //some public member
          int value() const { return _value; }
  };
  
  class Erasure //the type erasure
  {
      private:
          class Interface  //interface of the holder
          {
              public:
                  virtual double value() const = 0;
          };
  
          //holder template - implementing the interface
          template&lt;typename T&gt; class Holder:public Interface
          {
              public:
                  T _object;
              public:
                  //construct by copying o
                  Holder(const T &amp;o):_object(o) {}
                  //construct by moving o
                  Holder(T &amp;&amp;o):_object(std::move(o)) {}
                  //copy constructor
                  Holder(const Holder&lt;T&gt; &amp;o):_object(o._object) {}
                  //move constructor
                  Holder(Holder&lt;T&gt; &amp;&amp;o):_object(std::move(o._object)) {}
  
                  //implements the virtual member function
                  virtual double value() const
                  {
                      return double(_object.value());
                  }
          };
  
          Interface *_ptr; //pointer to holder
      public:
          //construction by copying o
          template&lt;typename T&gt; Erasure(const T &amp;o):
               _ptr(new Holder&lt;T&gt;(o))
          {}
  
          //construction by moving o
          template&lt;typename T&gt; Erasure(T &amp;&amp;o):
              _ptr(new Holder&lt;T&gt;(std::move(o)))
          {}
  
          //delegate
          double value() const { return _ptr-&gt;value(); }
  };
  
  int main(int argc,char **argv)
  {
      A a(100.2344);
      B b(-100);
  
      Erasure g1(std::move(a));
      Erasure g2(b);
  
      return 0;
  }
  </code></pre>
  
  <p>As a compiler I use gcc 4.7 on a Debian testing system. Assuming the code is stored in a file named <code>terasure.cpp</code> the build leads to the following error message</p>
  
  <pre><code>$&gt; g++ -std=c++0x -o terasure terasure.cpp
  terasure.cpp: In instantiation of ‘class Erasure::Holder&lt;B&amp;&gt;’:
  terasure.cpp:78:45:   required from ‘Erasure::Erasure(T&amp;&amp;) [with T = B&amp;]’
  terasure.cpp:92:17:   required from here
  terasure.cpp:56:17: error: ‘Erasure::Holder&lt;T&gt;::Holder(T&amp;&amp;) [with T = B&amp;]’ cannot be   overloaded
  terasure.cpp:54:17: error: with ‘Erasure::Holder&lt;T&gt;::Holder(const T&amp;) [with T = B&amp;]’
  terasure.cpp: In instantiation of ‘Erasure::Erasure(T&amp;&amp;) [with T = B&amp;]’:
  terasure.cpp:92:17:   required from here
  terasure.cpp:78:45: error: no matching function for call to   ‘Erasure::Holder&lt;B&amp;&gt;::Holder(std::remove_reference&lt;B&amp;&gt;::type)’
  terasure.cpp:78:45: note: candidates are:
  terasure.cpp:60:17: note: Erasure::Holder&lt;T&gt;::Holder(Erasure::Holder&lt;T&gt;&amp;&amp;) [with T = B&amp;]
  terasure.cpp:60:17: note:   no known conversion for argument 1 from ‘std::remove_reference&lt;B&amp;&gt;::type {aka B}’ to ‘Erasure::Holder&lt;B&amp;&gt;&amp;&amp;’
  terasure.cpp:58:17: note: Erasure::Holder&lt;T&gt;::Holder(const Erasure::Holder&lt;T&gt;&amp;) [with T = B&amp;]
  terasure.cpp:58:17: note:   no known conversion for argument 1 from ‘std::remove_reference&lt;B&amp;&gt;::type {aka B}’ to ‘const Erasure::Holder&lt;B&amp;&gt;&amp;’
  terasure.cpp:54:17: note: Erasure::Holder&lt;T&gt;::Holder(const T&amp;) [with T = B&amp;]
  terasure.cpp:54:17: note:   no known conversion for argument 1 from ‘std::remove_reference&lt;B&amp;&gt;::type {aka B}’ to ‘B&amp;’
  </code></pre>
  
  <p>It seems that for <code>Erasure g2(b);</code> the compiler still tries to use the move constructor. Is this intended behavior of the compiler? Do I missunderstand something in general with the type erasure pattern?  Does someone have an idea how to get this right?</p>