Wednesday, November 11, 2009

Emulating C++0x auto keyword in C++

GCC has a typeof(e) operator (more pedantically, __typeof__(e), as typeof is not in C99 nor C++89 standard) that can compute the type of any expression e. It's typically used by macros, whose arguments aren't typed, to create local variables that has the same type as its arguments. For example,

#define max(a, b) \
  ({ __typeof__(a) _a = (a), \
     __typeof__(b) _b = (b), \
     (_a >= _b)? _a : _b })

This definition of max(a, b) prevents evaluating the expressions a and b more than once. These expressions can cause side-effects, such as printing a message to the screen.

The typeof operator apparently also works for C++. It is sometimes awkward to write out the type of the whole expression. For example,

void foo() {
  std::vector<int> v;
  for (std::vector<int>::const_iterator iter = v.begin();
       iter != v.end();
       iter++) {
    /* ... */
  }
}

Writing the type for the iterator is cumbersome. In C++0x, this code can be written like this using the auto keyword.

void foo() {
  std::vector<int> v;
  for (auto iter = v.begin(); iter != v.end(); iter++) {
    /* ... */
  }
}

In C++, using the __typeof__ keyword, we can write a macro like this:

#define autovar(x, exp) __typeof__(exp) x = (exp)

And the code above would look like this:

void foo() {
  std::vector<int> v;
  for (autovar(iter, v.begin()); iter != v.end(); iter++) {
    /* ... */
  }
}

Here is another use of the typeof operator: sometimes C++ can't figure out how to instantiate a template, and manually writing the type arguments can be tedious. You can use __typeof__ to help the compiler figure out the correct template parameter.

Apparently Boost provides a BOOST_AUTO macro that uses pretty much the same technique.

In C++0x, the typeof keyword is called decltype.

No comments: