Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper behavior when overloading casts to have class behave identically to pointers

I want to have a class behave identically to pointers, but also support the comparison operators, like < and >.

I am running into casting troubles:

ptr_t<foo> x = new foo;
(bar*)x;              // cast should be allowed
static_cast<bar*>(x); // cast should fail

The above snippet should behave as if ptr_t<foo> was foo*.

Here is the cast operator:

template <typename cast_t>
explicit inline operator cast_t() {
  return (cast_t)(ptr); // causes static_cast to use C-style, which is bad
}

If I use C-style in the definition then static_cast becomes unsafe. If I use static_cast then the C-style becomes less useful. How can I fix this?

like image 938
Pubby Avatar asked May 29 '26 20:05

Pubby


1 Answers

You can easily emulate ptr_t<foo> acting like foo* by overloading the arrow and dereference operators, whilst providing a get function. This is how all smart pointer operate (by convention), and it's much more natural to work with. Messing around with casts seems needlessly complicated and fragile.

template <typename T>
struct ptr_t
{
    T* get() const;

    T* operator->() const
    {
        return get();
    }

    T& operator*() const
    {
        return *get();
    }
};

struct foo
{
    void bar() const;
};

void baz(foo*);

ptr_t<foo> x = /* .. */;

x->bar();
(*x).bar();
baz(x.get());
like image 102
GManNickG Avatar answered May 31 '26 09:05

GManNickG