Daniel Lemire's blog

, 3 min read

Why I like the new C++

I was reading Vivek Haldar’s post on the new C++ (C++11) and I was reminded that I need to write such a post myself.

C++ is a standardized language. And they came up with a new version of the standard called C++11. Usually, for complex languages like C++, new versions tend to make things worse. The reason is simple: every vendor is eager to see its features standardized. So the whole standardization process becomes highly political as mutually contradictory features must be glued on. But, for once, the design-by-committee process worked really well: C++11 is definitively superior to previous versions of C++.

In one of my recent research projects, we produced a C++ library leveraging several of the new features of C++11. The use of C++11 is still a bit problematic. For example, our library only compiles under GCC 4.7 and better or LLVM 3.2. So, why did we bother with C++11? 1. The move semantics

In conventional C++, values are either copied or passed by reference. If you are adding large objects (e.g., the data of an image) to a container such as an STL vector, then they are necessarily copied unless you do tricks involving pointers and other magical incantations. Performance-wise, this is absolutely terrible!

The new C++ introduces the move semantics: you can move data to a container (such as an STL vector) without copying it! For example, the following code took over 4s to run using the regular C++, and only 0.6s using C++11: it is a performance boost by a factor of 5, without changing a line of code.```C vector<vector > V; for(int k = 0; k < 100000; ++k) { vector x(1000); V.push_back(x); }



__2. No hassle initialization__

Initializing containers used to be a major pain in C++. It has now become ridiculously easy:
```C
const map<string,int> m = {{"Joe",2},{"Jack",3}};

There are still a few things that I could not get to work, such as initializing static members within the class itself. But, at least, you no longer waste minutes initializing a trivial data structure.

3. Auto

STL uses iterators. And iterators are cool. But old C++ forces you to fully qualify the type each time (e.g., vector::iterator) even when the compiler could deduce the type. It gets annoying and it makes the code hard to parse. C++11 is much better:

vector<int> x = {1,2,3,4};
for(auto i : x)
  cout<< i <<endl;

These lines of code initialize a container and print it out. I never want to go back to the old ways!

4. Constexpr

Suppose that you have a function that can be called safely by the compiler because it has no side effect: most mathematical functions are of this form. Think about a function that computes the square root of a number, or the greatest common diviser of two numbers.

In old-style C++, you often have to hard-code the result of these functions. For example, you cannot write enum{x=sqrt(9)}. Now you can! For example, let us define a simple constexpr function:

// returns the greater common divisor
constexpr int gcd(int x, int y) {
    return (x % y) == 0 ? y :  gcd(y,x % y);
}

If gcd was just any function, then it might be called multiple times in the following loop, but thanks to C++11, it will never get called when the program is running (just once by the compiler):

for(int k = 0; k < 100000; ++k) {
    vector<int> x(gcd(1000,100000)); 
    V.push_back(x);
}

(Naturally, a buggy C++ compiler might fail to optimize away the constexpr function call, but you can then file a bug report with your compiler vendor.)

Conclusion

C++11 is not yet supported by all compilers, but if you are serious about C++, you should switch to C++11 as fast as possible.

As usual, my code is available from github.