title: Type erasure techniques
body: <p><sup>(With type erasure, I mean hiding some or all of the type information regarding a class, somewhat like <a href="http://www.boost.org/doc/libs/1_46_0/doc/html/any.html" rel="noreferrer">Boost.Any</a>.)</sup><br>
  I want to get a hold of type erasure techniques, while also sharing those, which I know of. My hope is kinda to find some crazy technique that somebody thought of in his/her darkest hour. :) </p>
  
  <p>The first and most obvious, and commonly taken approach, that I know, are virtual functions. Just hide the implementation of your class inside an interface based class hierarchy. Many Boost libraries do this, for example <a href="http://www.boost.org/doc/libs/1_46_0/doc/html/any.html" rel="noreferrer">Boost.Any</a> does this to hide your type and <a href="http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm" rel="noreferrer">Boost.Shared_ptr</a> does this to hide the (de)allocation mechanic.  </p>
  
  <p>Then there is the option with function pointers to templated functions, while holding the actual object in a <code>void*</code> pointer, like <a href="http://www.boost.org/doc/libs/1_46_1/doc/html/function.html" rel="noreferrer">Boost.Function</a> does to hide the real type of the functor. Example implementations can be found at the end of the question.</p>
  
  <p>So, for my actual question:<br>
  What other type erasure techniques do you know of? Please provide them, if possible, with an example code, use cases, your experience with them and maybe links for further reading.</p>
  
  <p><strong>Edit</strong><br>
  (Since I wasn't sure wether to add this as an answer, or just edit the question, I'll just do the safer one.)<br>
  Another nice technique to hide the actual type of something <strong>without</strong> virtual functions or <code>void*</code> fiddling, is the one GMan employs <a href="https://stackoverflow.com/questions/2552839/which-c-standard-library-wrapper-functions-do-you-use/2553109#2553109">here</a>, with relevance to <a href="https://stackoverflow.com/questions/4985800/why-is-the-derived-classs-destructor-invoked-on-a-const-reference-to-the-base-cl">my question</a> on how exactly this works.</p>
  
  <hr>
  
  <p>Example code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  
  // NOTE: The class name indicates the underlying type erasure technique
  
  // this behaves like the Boost.Any type w.r.t. implementation details
  class Any_Virtual{
          struct holder_base{
                  virtual ~holder_base(){}
                  virtual holder_base* clone() const = 0;
          };
  
          template&lt;class T&gt;
          struct holder : holder_base{
                  holder()
                          : held_()
                  {}
  
                  holder(T const&amp; t)
                          : held_(t)
                  {}
  
                  virtual ~holder(){
                  }
  
                  virtual holder_base* clone() const {
                          return new holder&lt;T&gt;(*this);
                  }
  
                  T held_;
          };
  
  public:
          Any_Virtual()
                  : storage_(0)
          {}
  
          Any_Virtual(Any_Virtual const&amp; other)
                  : storage_(other.storage_-&gt;clone())
          {}
  
          template&lt;class T&gt;
          Any_Virtual(T const&amp; t)
                  : storage_(new holder&lt;T&gt;(t))
          {}
  
          ~Any_Virtual(){
                  Clear();
          }
  
          Any_Virtual&amp; operator=(Any_Virtual const&amp; other){
                  Clear();
                  storage_ = other.storage_-&gt;clone();
                  return *this;
          }
  
          template&lt;class T&gt;
          Any_Virtual&amp; operator=(T const&amp; t){
                  Clear();
                  storage_ = new holder&lt;T&gt;(t);
                  return *this;
          }
  
          void Clear(){
                  if(storage_)
                          delete storage_;
          }
  
          template&lt;class T&gt;
          T&amp; As(){
                  return static_cast&lt;holder&lt;T&gt;*&gt;(storage_)-&gt;held_;
          }
  
  private:
          holder_base* storage_;
  };
  
  // the following demonstrates the use of void pointers 
  // and function pointers to templated operate functions
  // to safely hide the type
  
  enum Operation{
          CopyTag,
          DeleteTag
  };
  
  template&lt;class T&gt;
  void Operate(void*const&amp; in, void*&amp; out, Operation op){
          switch(op){
          case CopyTag:
                  out = new T(*static_cast&lt;T*&gt;(in));
                  return;
          case DeleteTag:
                  delete static_cast&lt;T*&gt;(out);
          }
  }
  
  class Any_VoidPtr{
  public:
          Any_VoidPtr()
                  : object_(0)
                  , operate_(0)
          {}
  
          Any_VoidPtr(Any_VoidPtr const&amp; other)
                  : object_(0)
                  , operate_(other.operate_)
          {
                  if(other.object_)
                          operate_(other.object_, object_, CopyTag);
          }
  
          template&lt;class T&gt;
          Any_VoidPtr(T const&amp; t)
                  : object_(new T(t))
                  , operate_(&amp;Operate&lt;T&gt;)
          {}
  
          ~Any_VoidPtr(){
                  Clear();
          }
  
          Any_VoidPtr&amp; operator=(Any_VoidPtr const&amp; other){
                  Clear();
                  operate_ = other.operate_;
                  operate_(other.object_, object_, CopyTag);
                  return *this;
          }
  
          template&lt;class T&gt;
          Any_VoidPtr&amp; operator=(T const&amp; t){
                  Clear();
                  object_ = new T(t);
                  operate_ = &amp;Operate&lt;T&gt;;
                  return *this;
          }
  
          void Clear(){
                  if(object_)
                          operate_(0,object_,DeleteTag);
                  object_ = 0;
          }
  
          template&lt;class T&gt;
          T&amp; As(){
                  return *static_cast&lt;T*&gt;(object_);
          }
  
  private:
          typedef void (*OperateFunc)(void*const&amp;,void*&amp;,Operation);
  
          void* object_;
          OperateFunc operate_;
  };
  
  int main(){
          Any_Virtual a = 6;
          std::cout &lt;&lt; a.As&lt;int&gt;() &lt;&lt; std::endl;
  
          a = std::string("oh hi!");
          std::cout &lt;&lt; a.As&lt;std::string&gt;() &lt;&lt; std::endl;
  
          Any_Virtual av2 = a;
  
          Any_VoidPtr a2 = 42;
          std::cout &lt;&lt; a2.As&lt;int&gt;() &lt;&lt; std::endl;
  
          Any_VoidPtr a3 = a.As&lt;std::string&gt;();
          a2 = a3;
          a2.As&lt;std::string&gt;() += " - again!";
          std::cout &lt;&lt; "a2: " &lt;&lt; a2.As&lt;std::string&gt;() &lt;&lt; std::endl;
          std::cout &lt;&lt; "a3: " &lt;&lt; a3.As&lt;std::string&gt;() &lt;&lt; std::endl;
  
          a3 = a;
          a3.As&lt;Any_Virtual&gt;().As&lt;std::string&gt;() += " - and yet again!!";
          std::cout &lt;&lt; "a: " &lt;&lt; a.As&lt;std::string&gt;() &lt;&lt; std::endl;
          std::cout &lt;&lt; "a3-&gt;a: " &lt;&lt; a3.As&lt;Any_Virtual&gt;().As&lt;std::string&gt;() &lt;&lt; std::endl;
  
          std::cin.get();
  }
  </code></pre>