The Biggest Changes in C++11 (and Why You Should Care)

It’s been 13 years since the first iteration of the C++ language. Danny Kalev, a former member of the C++ standards committee, explains how the programming language has been improved and how it can help you write better code.
c-small_Bjarne Stroustrup, the creator of C++, said recently that C++11 “feels like a new language — the pieces just fit together better.” Indeed, core C++11 has changed significantly. It now supports lambda expressions, automatic type deduction of objects, uniform initialization syntax, delegating constructors, deleted and defaulted function declarations, nullptr, and most importantly, rvalue references — a feature that augurs a paradigm shift in how one conceives and handles objects. And that’s just a sample.

The C++11 Standard Library was also revamped with new algorithms, new container classes, atomic operations, type traits, regular expressions, new smart pointers, async() facility, and of course a multithreading library.

A complete list of the new core and library features of C++11 is available here.

After the approval of the C++ standard in 1998, two committee members prophesied that the next C++ standard would “certainly” include a built-in garbage collector (GC), and that it probably wouldn’t support multithreading because of the technical complexities involved in defining a portable threading model. Thirteen years later, the new C++ standard, C++11, is almost complete. Guess what? It lacks a GC but it does include a state-of–the-art threading library.

In this article I explain the biggest changes in the language, and why they are such a big deal. As you’ll see, threading libraries are not the only change. The new standard builds on the decades of expertise and makes C++ even more relevant. As Rogers Cadenhead points out, “That’s pretty amazing for something as old as disco, Pet Rocks, and Olympic swimmers with chest hair.”

First, let’s look at some of the prominent C++11 core-language features.

Lambda Expressions

A lambda expression lets you define functions locally, at the place of the call, thereby eliminating much of the tedium and security risks that function objects incur. A lambda expression has the form:

[capture](parameters)->return-type {body}

The [] construct inside a function call’s argument list indicates the beginning of a lambda expression. Let’s see a lambda example.

Suppose you want to count how many uppercase letters a string contains. Using for_each() to traverses a char array, the following lambda expression determines whether each letter is in uppercase. For every uppercase letter it finds, the lambda expression increments Uppercase, a variable defined outside the lambda expression:

int main()
   char s[]="Hello World!";
   int Uppercase = 0; //modified by the lambda
   for_each(s, s+sizeof(s), [&Uppercase] (char c) {
    if (isupper(c))
 cout<< Uppercase<<" uppercase letters in: "<< s<<endl;

It’s as if you defined a function whose body is placed inside another function call. The ampersand in [&Uppercase] means that the lambda body gets a reference to Uppercase so it can modify it. Without the ampersand, Uppercase would be passed by value. C++11 lambdas include constructs for member functions as well.

Automatic Type Deduction and decltype

In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object’s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:

auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long

Automatic type deduction is chiefly useful when the type of the object is verbose or when it’s automatically generated (in templates). Consider:

void func(const vector<int> &vi)
vector<int>::const_iterator ci=vi.begin();

Instead, you can declare the iterator like this:

auto ci=vi.begin();

The keyword auto isn’t new; it actually dates back the pre-ANSI C era. However, C++11 has changed its meaning; auto no longer designates an object with automatic storage type. Rather, it declares an object whose type is deducible from its initializer. The old meaning of auto was removed from C++11 to avoid confusion.

C++11 offers a similar mechanism for capturing the type of an object or an expression. The new operator decltype takes an expression and “returns” its type:

const vector<int> vi;
typedef decltype (vi.begin()) CIT;
CIT another_const_iterator;

Uniform Initialization Syntax

C++ has at least four different initialization notations, some of which overlap.

Parenthesized initialization looks like this:

std::string s("hello");
int m=int(); //default initialization

You can also use the = notation for the same purpose in certain cases:

std::string s="hello";
int x=5;

For POD aggregates, you use braces:

int arr[4]={0,1,2,3};
struct tm today={0};

Finally, constructors use member initializers:

struct S {
 int x;
 S(): x(0) {} };

This proliferation is a fertile source for confusion, not only among novices. Worse yet, in C++03 you can’t initialize POD array members and POD arrays allocated using new[]. C++11 cleans up this mess with a uniform brace notation:

class C
int a;
int b;
 C(int i, int j);

C c {0,0}; //C++11 only. Equivalent to: C c(0,0);

int* a = new int[3] { 1, 2, 0 }; /C++11 only

class X {
  int a[4];
  X() : a{1,2,3,4} {} //C++11, member array initializer

With respect to containers, you can say goodbye to a long list of push_back() calls. In C++11 you can initialize containers intuitively:

// C++11 container initializer
vector<string> vs={ "first", "second", "third"};
map singers =
  { {"Lady Gaga", "+1 (212) 555-7890"},
    {"Beyonce Knowles", "+1 (212) 555-0987"}};

Similarly, C++11 supports in-class initialization of data members:

class C
 int a=7; //C++11 only

Deleted and Defaulted Functions

A function in the form:

struct A
 A()=default; //C++11
 virtual ~A()=default; //C++11

is called a defaulted function. The =default; part instructs the compiler to generate the default implementation for the function. Defaulted functions have two advantages: They are more efficient than manual implementations, and they rid the programmer from the chore of defining those functions manually.

The opposite of a defaulted function is a deleted function:

int func()=delete;

Deleted functions are useful for preventing object copying, among the rest. Recall that C++ automatically declares a copy constructor and an assignment operator for classes. To disable copying, declare these two special member functions =delete:

struct NoCopy
 NoCopy & operator =( const NoCopy & ) = delete;
 NoCopy ( const NoCopy & ) = delete;
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted


At last, C++ has a keyword that designates a null pointer constant. nullptr replaces the bug-prone NULL macro and the literal 0 that have been used as null pointer substitutes for many years. nullptr is strongly-typed:

void f(int); //#1
void f(char *);//#2
f(0); //which f is called?
f(nullptr) //unambiguous, calls #2

nullptr is applicable to all pointer categories, including function pointers and pointers to members:

const char *pc=str.c_str(); //data pointers
if (pc!=nullptr)
int (A::*pmf)()=nullptr; //pointer to member function
void (*pmf)()=nullptr; //pointer to function

Delegating Constructors

In C++11 a constructor may call another constructor of the same class:

class M //C++11 delegating constructors
 int x, y;
 char *p;
 M(int v) : x(v), y(0), p(new char [MAX]) {} //#1 target
 M(): M(0) {cout<<"delegating ctor"<<endl;} //#2 delegating

Constructor #2, the delegating constructor, invokes the target constructor #1.

Rvalue References

Reference types in C++03 can only bind to lvalues. C++11 introduces a new category of reference types called rvalue references. Rvalue references can bind to rvalues, e.g. temporary objects and literals.

The primary reason for adding rvalue references is move semantics. Unlike traditional copying, moving means that a target object pilfers the resources of the source object, leaving the source in an “empty” state. In certain cases where making a copy of an object is both expensive and unnecessary, a move operation can be used instead. To appreciate the performance gains of move semantics, consider string swapping. A naive implementation would look like this:

void naiveswap(string &a, string & b)
 string temp = a;

This is expensive. Copying a string entails the allocation of raw memory and copying the characters from the source to the target. In contrast, moving strings merely swaps two data members, without allocating memory, copying char arrays and deleting memory:

void moveswapstr(string& empty, string & filled)
//pseudo code, but you get the idea
 size_t sz=empty.size();
 const char *p=;
//move filled's resources to empty
//filled becomes empty

If you’re implementing a class that supports moving, you can declare a move constructor and a move assignment operator like this:

class Movable
Movable (Movable&&); //move constructor
Movable&& operator=(Movable&&); //move assignment operator

The C++11 Standard Library uses move semantics extensively. Many algorithms and containers are now move-optimized.

C++11 Standard Library

C++ underwent a major facelift in 2003 in the form of the Library Technical Report 1 (TR1). TR1 included new container classes (unordered_set, unordered_map, unordered_multiset, and unordered_multimap) and several new libraries for regular expressions, tuples, function object wrapper and more. With the approval of C++11, TR1 is officially incorporated into standard C++ standard, along with new libraries that have been added since TR1. Here are some of the C++11 Standard Library features:

Threading Library

Unquestionably, the most important addition to C++11 from a programmer’s perspective is concurrency. C++11 has a thread class that represents an execution thread, promises and futures, which are objects that are used for synchronization in a concurrent environment, the async() function template for launching concurrent tasks, and the thread_local storage type for declaring thread-unique data. For a quick tour of the C++11 threading library, read Anthony Williams’ Simpler Multithreading in C++0x.

New Smart Pointer Classes

C++98 defined only one smart pointer class, auto_ptr, which is now deprecated. C++11 includes new smart pointer classes: shared_ptr and the recently-added unique_ptr. Both are compatible with other Standard Library components, so you can safely store these smart pointers in standard containers and manipulate them with standard algorithms.

New C++ Algorithms

The C++11 Standard Library defines new algorithms that mimic the set theory operations all_of(), any_of() and none_of(). The following listing applies the predicate ispositive() to the range [first, first+n) and uses all_of(), any_of() and none_of() to examine the range’s properties:

#include <algorithm>
//C++11 code
//are all of the elements positive?
all_of(first, first+n, ispositive()); //false
//is there at least one positive element?
any_of(first, first+n, ispositive());//true
// are none of the elements positive?
none_of(first, first+n, ispositive()); //false

A new category of copy_n algorithms is also available. Using copy_n(), copying an array of 5 elements to another array is a cinch:

int source[5]={0,12,34,50,80};
int target[5];
//copy 5 elements from source to target

The algorithm iota() creates a range of sequentially increasing values, as if by assigning an initial value to *first, then incrementing that value using prefix ++. In the following listing, iota() assigns the consecutive values {10,11,12,13,14} to the array arr, and {‘a’, ‘b’, ‘c’} to the char array c.

include <numeric>
int a[5]={0};
char c[3]={0};
iota(a, a+5, 10); //changes a to {10,11,12,13,14}
iota(c, c+3, 'a'); //{'a','b','c'}

C++11 still lacks a few useful libraries such as an XML API, sockets, GUI, reflection — and yes, a proper automated garbage collector. However, it does offer plenty of new features that will make C++ more secure, efficient (yes, even more efficient than it has been thus far! See Google’s benchmark tests), and easier to learn and use.

If the changes in C++11 seem overwhelming, don’t be alarmed. Take the time to digest these changes gradually. At the end of this process you will probably agree with Stroustrup: C++11 does feel like a new language — a much better one.

See also:



  1. Karel Burda says:

    Very useful post, all the new features put in a nutshell. Thanks.

  2. Jim Watkins says:

    Thanks for the concise summary.

  3. C++11 in 10 minutes. Complex topics explained elegantly and easy to understand way.

  4. Very Simple, but great way to put it all together.

  5. Prasad Patnaik says:

    Thanks for the post. A Good Brief explanation of The new features which more importantly explains – “The Wish list from the Older Version”

  6. sundeep singh says:

    Thanks a lot… C++11 major features explained in such an easy and short article!

  7. wow. i still have so much to catch up on I haven’t even effectively learned C++ yet.  
    and I call myself trying to build my own language -_-

  8. I’ve only read the comments… they are so good that I have to read the article now!!! ;-)) 

  9. edelcides says:

    Thank you for the article, It is a great one, well written and straight to the point. I found It easy to understand despite the fact of been new to C++.

  10. FYI, the article you link to in the second-to-last paragraph is about a study that wasn’t particularly well done and was generally not considered valid within Google.

  11. Nice and useful post, thanks! 
    Just noting that were GC capabilities incorporated into the language, the RT industry would have dumped this standard altogether, so great call on their side for not incorporating it.

  12. warrenPeace says:

    It’s about time that C++ incorporated these features that have been available in other languages for years! It might even win back some converts to Java and Matlab; like me.

  13. Great Job!!! Better than any book in only ten minutes!!!

  14. SmithAndKelly says:

    You should write a book !! Love it. An awesome introduction

  15. Σουηδός says:

    Great post! Keep on going!

  16. Kapil Awasthi says:

    initialization of vectors and maps in one line is just awesome. Earlier initializing vectors was so tedious… c++ 11 thumbs up

  17. “C++11 still lacks … a proper automated garbage collector.”
    That’s actually one of the coolest aspects of C++. If you need GC, there’s plenty different languages to choose from. Not to mention Boehm GC which is readily available.

  18. Wow, every iteration of C++ digs a bigger hole. Appalling syntax, comical template library implementation, and complete and utter lack of readability. It is no wonder that few people would choose to write in C++. I like the performance, but everything else is a tragedy.

    My evidence? Ask any experienced programmer *not* familiar with C++ 11 what these mean:

    NoCopy & operator =( const NoCopy & ) = delete
    virtual ~A()=default

    • Sensor5Answer says:


      We can actually say exactly the same thing about any other programming language out there… “New features” means that even experienced programmers most first study them before actually applying them. That applies across the board to any programming language.

      The main difference between them and C++? Well, for starters, quite a few rather well-informed people out there consider C++ as a solid programming language that successfully accommodates several programming paradigms at once (procedural, structured, OOP, and Generic).

      In addition to that, most other alternatives to C++ suck (you can use uppercase here for emphasis) in terms not only of syntax and gratuitous verbosity, but also in terms of performance when measured as a function of speed, efficiency, and memory use.

      If you do not like C++, fine, nothing stops you from using whatever suits your fancy, but remember that at the end the alternatives will most probably run up to 20 times slower, or force you to use a nonsensical, impractical memory and runtime model, or impose an arbitrarily and unnecessary syntax and object model, or a combination thereof, but your mileage might vary…

    • Pfft.

      If you throw prolog, lisp, haskell or erlang at someone, you’ll get the same effect.
      Even in C# you can make fairly obscure constructs as well.

      It is not a tragedy.

      C++ requires discipline and a lot of experience, but payoff is great. If you don’t like the language, use something else.

  19. ‘auto’ loosely type vs ‘nullptr’ strong typed? Left hand doesn’t know what right hand is doing.

  20. Danny Kalev says:

    auto isn’t loosely typed. It captures the type of the initializer. You can’t foll around with it too much. nullptr is strongly type to a certain extent (it’s always a pointer, but the pointer’s type is derived from the declaration. nullptr can also be applied to pointers to members btw).

  21. A lot of features are plain stupid – they just sucking it all out of their thumb.
    Will now check out what abominations they’ve brought in in C++14.

  22. David Ohlemacher says:

    map singer… results in ‘missing template arguments’. Needs to be map.

    Nice summary. I was looking for info on initialization lists as I start to read BJ’s book.

    I dont get the ‘look at the ugly valid syntax….” comments. Python can be very ugly to if you wish to write obtusely. Here is a good quote to code by: “Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” Brian W. Kernighan

  23. David Ohlemacher says:

    Hmm, webpage stripped out the correct singer type. Use string, string for the map’s key, value types.

  24. Very useful and clear, with simple and practical examples.
    Thanks a lot for sharing it!

  25. You will never see reflection in C++ standard as long as Bjarne lives. To incorporate it, would break the holy grail of C++, that you never have to pay for something you don’t use. That is the philosophy making C++ still be alive as a language to be reckon.

  26. Excellent summary of the new standard indeed. The new standard i.e. C++11 does makes C++ a whole new beast altogether. Well C++ was always the most powerful , fast, and the favorite language besides C. But this standard takes the whole language to a new level, like a whole new paradigm shift.

    The new library contains almost everything a standard should contain and add so much more. Couple that with Boost and you got yourself again a beautiful, feature rich, easy to express , powerful, fast programming language, which every system programmer aspires to use.

    Anyways thanks for sharing this wonderful article.

  27. Thank you for the article, It is a great one, well written and straight to the point. I found It easy to understand despite the fact of been new to C++.

  28. Great summary of the C++11 update. However, I wouldn’t agree that C++ is missing a garbage collector. This is intentionally left out because C++ has chosen a different path of using RAII and resource management instead of garbage collection.

  29. Henri de Feraudy says:

    One of the most productive reads I have ever undertaken.

  30. very useful article! itoa I didn’t notice that

  31. satyanarayana says:

    very useful and clear with a simple examples. thank you for providing it.

  32. Ariel Almario says:

    Great post. All new great features of C++11 are clearly explained in this article.

  33. Paul Epstein says:

    “Without the ampersand, Uppercase would be passed by value.”
    This is incorrect. With “=” instead of ampersand, you get a compile error
    because lambdas can’t modify objects which are passed by value unless
    you use the keyword mutable.

  34. very nice article to understand c++ 11 features in just few minutes.

    Thanks a lot.

  35. Very well explained and arranged to grasp the c++11 updates so precisely.

Speak Your Mind