The long arrow operator in C++

Sometimes, we need to create wrapper types. For example, types like unique_ptrshared_ptroptional and similar.

Usually, these types have an accessor member function called .get but they also provide the operator-> to support direct access to the contained value similarly to what ordinary pointers do.
unnamed

The problem is that sometimes we have a few of these types nested into each other. This means that we need to call .get multiple times, or to have a lot of dereference operators until we reach the value.

Something like this:

 wrap<wrap<std::string>> wp;
    wp.get().get().length();
    wp.get()->length();

This can be a bit ugly. If we can replace one .get() with an arrow, it would be nice if we could replace the second .get() as well. For this, the C++98 introduced a long arrow operator.

wrap<wrap<std::string>> wp;
    wp--->length();

What if we have another layer of wrapping? Just make a longer arrow.

 wrap<wrap<wrap<std::string>>> wp;
    wp----->length();

With a special implementation of wrap, this compiles and works without many problems.

Disclaimer

Now, before we continue, you should realize that this post is not a serious one. And that this should never be used in a serious project, just like the left arrow operator <-- [1] and the WTF operator ??!??! [2] (which no longer works in C++17 BTW).

How?

Like in the <-- case, the long arrow is not a single operator, but a combination of multiple operators. In this case, a normal -> operator and the postfix decrement operator --.

So, when we write wp----->length(), the compiler sees ((wp--)--)->length().

If we define the postfix -- to be the same as the dereference operator, we get the long arrow, and the even longer arrow operators:

template <typename T>
class wrap {
public:
    T* operator->()    { return &t; }
    T& operator--(int) {  return t; }

private:
    T t;
};

Original source – http://cukic.co/
By Ivan Čukić 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s