Computing the level of indirection for pointer types

I’ve finally had a little time to advance with reading Alexandrescu’s book on Modern C++ design, and I’m absolutely blown away by the sheer awesomeness of its ideas. I highly recommend getting this book!

I would like to show just a little bit of what we can do with template specialization when it comes down to meta programming.

Suppose we wanted to know how many levels of indirection does our type actually have. What I mean in “levels of indirection” is basically how many times do we need to de-reference the type in order to get to the real underlying type. Here’s how it’s possible to achieve just that, in compile time, using template specializations:

template <typename T>
struct LevelOfIndirection {
    enum { result = 0 };
    typedef T pointedToType;
};

template <typename T>
struct LevelOfIndirection<T*> {
    enum { result = LevelOfIndirection<T>::result + 1 };
    typedef typename LevelOfIndirection<T>::pointedToType pointedToType;
};

#include <iostream>

int main () {
    std::cout <<
        "int**: " << LevelOfIndirection<int**>::result <<
        ", int: " << LevelOfIndirection<int>::result <<
        std::endl;
    // LevelOfIndirection<int**>::pointedToType is int!
}

The second specialization matches pointer types better and therefore gets selected by the compiler as long as T represents a pointer type. So by using it, we’re able to make all the calculations we’re interested in.

This is just something I came up with to demonstrate the power in yielding template specializations for meta programming. There are many other interesting techniques I plan to introduce in the near future.

5 thoughts on “Computing the level of indirection for pointer types

    1. Well, I could come up with some bizzare scenario, but the point I want to make is a little different..
      This code is presented as an original example (perhaps too original?) for this kind of technique/approach. The very same technique can be applied in many real-life situations, and this simple example only strives to demonstrate the basic concept – in order to get people familiar with this kind of thinking.

  1. Hi Roman,

    Great post!

    I can think of a use for this code. With some basic type specialization we can assign a unique ID for each type in our program.

    Nadav

  2. Here you have an example where this is useful:

    pointer_cast and safe_reinterpret_cast.

    char* p = pointer_cast(new int()); // OK
    long p = pointer_cast(new int()); // Error
    int** p = pointer_cast(new int()); // Error

    char p = safe_reinterpret_cast(new int()); // Checks size
    long p = safe_reinterpret_cast(new int()); // Checks size

    http://rsdn.ru/forum/src/1871852.1.aspx

    Enjoy :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>