When should you use constexpr capability in C++11?

Suppose it does something a little more complicated.

constexpr int MeaningOfLife ( int a, int b ) { return a * b; }

const int meaningOfLife = MeaningOfLife( 6, 7 );

Now you have something that can be evaluated down to a constant while maintaining good readability and allowing slightly more complex processing than just setting a constant to a number.

It basically provides a good aid to maintainability as it becomes more obvious what you are doing. Take max( a, b ) for example:

template< typename Type > constexpr Type max( Type a, Type b ) { return a < b ? b : a; }

Its a pretty simple choice there but it does mean that if you call max with constant values it is explicitly calculated at compile time and not at runtime.

Another good example would be a DegreesToRadians function. Everyone finds degrees easier to read than radians. While you may know that 180 degrees is 3.14159265 (Pi) in radians it is much clearer written as follows:

const float oneeighty = DegreesToRadians( 180.0f );

Lots of good info here:

http://en.cppreference.com/w/cpp/language/constexpr


Introduction

constexpr was not introduced as a way to tell the implementation that something can be evaluated in a context which requires a constant-expression; conforming implementations has been able to prove this prior to C++11.

Something an implementation cannot prove is the intent of a certain piece of code:

  • What is it that the developer want to express with this entity?
  • Should we blindly allow code to be used in a constant-expression, just because it happens to work?

What would the world be without constexpr?

Let's say you are developing a library and realize that you want to be able to calculate the sum of every integer in the interval (0,N].

int f (int n) {
  return n > 0 ? n + f (n-1) : n;
}

The lack of intent

A compiler can easily prove that the above function is callable in a constant-expression if the argument passed is known during translation; but you have not declared this as an intent - it just happened to be the case.

Now someone else comes along, reads your function, does the same analysis as the compiler; "Oh, this function is usable in a constant-expression!", and writes the following piece of code.

T arr[f(10)]; // freakin' magic

The optimization

You, as an "awesome" library developer, decide that f should cache the result when being invoked; who would want to calculate the same set of values over and over?

int func (int n) { 
  static std::map<int, int> _cached;

  if (_cached.find (n) == _cached.end ()) 
    _cached[n] = n > 0 ? n + func (n-1) : n;

  return _cached[n];
}

The result

By introducing your silly optimization, you just broke every usage of your function that happened to be in a context where a constant-expression was required.

You never promised that the function was usable in a constant-expression, and without constexpr there would be no way of providing such promise.


So, why do we need constexpr?

The primary usage of constexpr is to declare intent.

If an entity isn't marked as constexpr - it was never intended to be used in a constant-expression; and even if it is, we rely on the compiler to diagnose such context (because it disregards our intent).


Take std::numeric_limits<T>::max(): for whatever reason, this is a method. constexpr would be beneficial here.

Another example: you want to declare a C-array (or a std::array) that is as big as another array. The way to do this at the moment is like so:

int x[10];
int y[sizeof x / sizeof x[0]];

But wouldn’t it be better to be able to write:

int y[size_of(x)];

Thanks to constexpr, you can:

template <typename T, size_t N>
constexpr size_t size_of(T (&)[N]) {
    return N;
}