'any' class implementation
Your code is in pretty much good shape but there are still several issues apart from what mentioned by ChrisW:


There are many cases in input arguments and return types of functions where you are not particularly careful about const/non-const and value vs. reference.
This code won't work for built-in arrays, hence neither for C-style strings. One way is to decay the type of the input argument before storage; built-in arrays are decayed to pointers in this case (which means array elements are not really copied).
The default constructor shouldn't allocate anything; initialize the data pointer to nullptr and provide member functions empty() and clear() to control the state of having/not having data.
Your assignment operators are unnecessarily complex, inefficient (by self-tests) and not exception-safe (if new throws, the current object is already destroyed). The most elegant solution to all these issues is the copy-swap idiom, where all actual work is done by constructors alone.
You don't need typeid to test for type equality; a lightweight (but low-level) solution without RTTI is here.
Type identification should be kept as an internal detail; the minimal required functionality is type equality by is(); don't expose type(), rather keep it as private as possible.
Type checking is a good thing, but for performance you should also provide unchecked access.
Casting is from a base to a derived class, so need not (and should not) be done with reinterpret_cast; rather, dynamic_cast / static_cast for checked / unchecked access. dynamic_cast to a reference type will automatically throw an std::bad_cast if the object is not of the right type, so there is not need to manually check with is(). This does need RTTI but is more elegant.
Storing empty objects (like function objects) is currently inefficient, as it does need extra space on top of the virtual function table. This can be solved by the empty base optimization, which is done automatically by using std::tuple.
Implicit conversion operators are a possible source for ambiguities and confusion; you may keep them if you need their convenience, but use carefully (e.g. try to explicitly initialize an object of the right type).
Comparison operators are a clear overkill (if you have them, why not also have arithmetic operators, and so on?). If you still want them, define them as non-member functions, using public members is and cast to implement them.
There are no move semantics.
There is no specialized binary (non-member) function swap. Defaulting to std::swap is not as efficient as it involves three move operations; without move semantics, things are even worse as it involves three copy operations.


I took the liberty to re-factor your code to a great extent, and here is the result, resolving all issues above:

class some
{
    using id = size_t;

    template&lt;typename T&gt;
    struct type { static void id() { } };

    template&lt;typename T&gt;
    static id type_id() { return reinterpret_cast&lt;id&gt;(&amp;type&lt;T&gt;::id); }

    template&lt;typename T&gt;
    using decay = typename std::decay&lt;T&gt;::type;

    template&lt;typename T&gt;
    using none = typename std::enable_if&lt;!std::is_same&lt;some, T&gt;::value&gt;::type;

    struct base
    {
        virtual ~base() { }
        virtual bool is(id) const = 0;
        virtual base *copy() const = 0;
    } *p = nullptr;

    template&lt;typename T&gt;
    struct data : base, std::tuple&lt;T&gt;
    {
        using std::tuple&lt;T&gt;::tuple;

        T       &amp;get()      &amp; { return std::get&lt;0&gt;(*this); }
        T const &amp;get() const&amp; { return std::get&lt;0&gt;(*this); }

        bool is(id i) const override { return i == type_id&lt;T&gt;(); }
        base *copy()  const override { return new data{get()}; }
    };

    template&lt;typename T&gt;
    T &amp;stat() { return static_cast&lt;data&lt;T&gt;&amp;&gt;(*p).get(); }

    template&lt;typename T&gt;
    T const &amp;stat() const { return static_cast&lt;data&lt;T&gt; const&amp;&gt;(*p).get(); }

    template&lt;typename T&gt;
    T &amp;dyn() { return dynamic_cast&lt;data&lt;T&gt;&amp;&gt;(*p).get(); }

    template&lt;typename T&gt;
    T const &amp;dyn() const { return dynamic_cast&lt;data&lt;T&gt; const&amp;&gt;(*p).get(); }

public:
     some() { }
    ~some() { delete p; }

    some(some &amp;&amp;s)      : p{s.p} { s.p = nullptr; }
    some(some const &amp;s) : p{s.p-&gt;copy()} { }

    template&lt;typename T, typename U = decay&lt;T&gt;, typename = none&lt;U&gt;&gt;
    some(T &amp;&amp;x) : p{new data&lt;U&gt;{std::forward&lt;T&gt;(x)}} { }

    some &amp;operator=(some s) { swap(*this, s); return *this; }

    friend void swap(some &amp;s, some &amp;r) { std::swap(s.p, r.p); }

    void clear() { delete p; p = nullptr; }

    bool empty() const { return p; }

    template&lt;typename T&gt;
    bool is() const { return p ? p-&gt;is(type_id&lt;T&gt;()) : false; }

    template&lt;typename T&gt; T      &amp;&amp;_()     &amp;&amp; { return std::move(stat&lt;T&gt;()); }
    template&lt;typename T&gt; T       &amp;_()      &amp; { return stat&lt;T&gt;(); }
    template&lt;typename T&gt; T const &amp;_() const&amp; { return stat&lt;T&gt;(); }

    template&lt;typename T&gt; T      &amp;&amp;cast()     &amp;&amp; { return std::move(dyn&lt;T&gt;()); }
    template&lt;typename T&gt; T       &amp;cast()      &amp; { return dyn&lt;T&gt;(); }
    template&lt;typename T&gt; T const &amp;cast() const&amp; { return dyn&lt;T&gt;(); }

    template&lt;typename T&gt; operator T     &amp;&amp;()     &amp;&amp; { return std::move(_&lt;T&gt;()); }
    template&lt;typename T&gt; operator T      &amp;()      &amp; { return _&lt;T&gt;(); }
    template&lt;typename T&gt; operator T const&amp;() const&amp; { return _&lt;T&gt;(); }
};


I call it some instead of any because I prefer to hold something rather than anything :-) Plus, any is a common name for a function (like all), which is not the case for some.

Members cast() provide type-checked access, while members _() (shortest notation) provide unchecked access. I have chosen to give conversion operators unchecked access for performance but you are free to change that or remove them altogether.

I've also made a live example, including an extensive series of tests to demonstrate (almost) all possible uses.

Note that base (your dummy) now has a virtual destructor.

There is one more issue: using the free store is serious performance bottleneck when it comes to small types. What you can do is define a particular size to be allocated on stack, and only use the free store for larger objects, similar to short (or small) string optimization.

More generally, it is a good idea to parametrize the implementation with respect to how memory management (allocation, deallocation) is done by providing a kind of allocator object. any is really a container, even if of at most one object.

I have extended the implementation towards this direction but I will probably post this as a separate answer.