Deciphering C++ Types

When I first encountered a type declaration like char const * const *, I’d either curl up in a ball or spend several minutes puzzling through it. No more.

The right-left rule

Start at the identifier, sweep right translating symbols to words, then sweep left. Here’s the translation table:

SymbolMeaning
*pointer to
&reference to
constconstant
[]array of
()function returning

Example: char const * const * id

  • Start at id.
  • Sweep right: nothing.
  • Sweep left: * → pointer to; const → constant; * → pointer to; const char → constant character.

Result: “id is a pointer to a constant pointer to a constant character.”

The order of const relative to char doesn’t matter — const char * and char const * are identical.

More examples

const double * const & id → “id is a reference to a constant pointer to a constant double.”

int *id[]

  • Sweep right from id: [] → array of.
  • Sweep left: * → pointer to; int.

→ “id is an array of pointers to int.”

Parentheses

When you encounter ) while sweeping right, stop. Sweep left until you hit the matching (, then go back outside.

int (**id)();
  1. Start at id.
  2. Sweep right, hit ) immediately — stop.
  3. Sweep left: * → pointer to; * → pointer to; hit ( — stop.
  4. Sweep right outside the parens: () → function returning.
  5. Sweep left outside: int.

→ “id is a pointer to a pointer to a function returning int.”

Cheat sheet

DeclarationReading
int idint
int *idpointer to int
int &idreference to int
int * const idconstant pointer to int
int **idpointer to a pointer to int
int id[][]array of arrays of int
int (*id[])()array of pointers to functions returning int
int (*id())()function returning a pointer to a function returning int

One final monster:

int (*(*id)(char *, double))[9][20]

→ “id is a pointer to a function taking a char* and a double, returning a pointer to a 9-element array of 20-element arrays of int.”

This rule handles 99% of C++ declarations you’ll encounter in practice. Happy deciphering.