Pointer handle - only allocates in stack
I would expect operator+ and operator- to return a new object (leaving the current one intact.

    Ptr&amp; operator+(int i) {
        index += i;
        check_range(index);
        p+= i;
        return *this;
    }
    Ptr&amp; operator-(int i) {
        index -= i;
        check_range(index);
        p -= i;
        return *this;
    }


If I was using normal pointers.

 T* x  = getAT();
 x + 1;           // Does not change x
 T* y = x + 1;    // Does not change x (but y has the value of x+1).


Usually you see operator+ defined in terms of operator+=

Ptr&amp; operator+(int i) {
   Ptr result(*this);
   return result+=1;
}


The *this = *this+1; look very strange.

    Ptr&amp; operator++() {
        *this = *this+1;
        return *this;
    }


I would have just called the operator+=

    Ptr&amp; operator++() {
        return operator+=(1);
    }


Again don't like ++(*this);

    Ptr operator++(int) {
        Ptr&lt;T&gt; old{p};
        ++(*this);
        return old;
    }


I would have used:

    Ptr operator++(int) {
        Ptr&lt;T&gt; old{p};
        operator++();
        return old;
    }


You should strive for the strong exception guarantee (also known as transaction exception guarantee).

    void check_range(int i) {
        if (i &lt; 0 || i &gt; sz-1) {
            throw std::out_of_range("out of range");
        }
    }


Though this code looks like it does that. It is usually called in a way that prevents it.

    index -= i;
    check_range(index);  // If this throws your object is now in the new state
                         // with index out of range. I would have tried to make sure
                         // that if an exception is thrown then the state of the object
                         // remains unchanged.


    // Change to this:

    check_range(index - i); // If it throws then the object is still
                            // in a consistent unchanged state.
    index -= 1;             // If we get here then change the state.