08 May 2014

Constification in C++11

Here’s a neat little pattern. Suppose you want to initialise some object using mutating operations, and thereafter make the object const, without any overhead. In C++11 you can do just that with a lambda:

const auto v = []{
  vector<int> v;
  for (auto i = 0; i < 10; ++i)
    v.push_back(i * 10);
  return v;
}();

This “inline builder pattern” turns out to be a nice way to encapsulate mutation to smaller scope, thereby making your code a bit easier to reason about. Of course, the drawback of this is that objects you would initialise this way are the sorts of objects you might prefer to move rather than copy, and const interferes with that; but that is a problem in C++11 generally.

It goes to show that lambdas make working with const things a bit nicer all around. This pattern also lets you initialise const members in an object:

struct X {
  X()
    : x([]{
      auto s = 0;
      auto i = 10;
      while (i) s += --i;
      return s;
    }())
    {}
  const int x;
};

Ugly, but it gets the job done. That’s C++ for you.