T B H P N

C++11: Language and Libraries

additions and changes

New and modified Language Features:

The C++ programming language has been standardized in 1998, 2003, and again in 2011, with a new standard revision approved in 2014 and a significant revision expected in 2017. The Visual Studio 2013 C++ compiler implements most of the 2011 changes and a few of the 2014 changes. The 2011 changes are discussed on this page.

  1. compiler created functions:

    Every class designer should consciously decide to implement these, or use the compiler generated versions, or prohibit them. Generated members will be correct only if every data member of the class has correct semantics for each one. Usually if we implement one then we do so for all. Note: if any constructor or destructor has an =default suffix then the compiler will generate that operation. We won't keep stating this for each of the functions below.

    Test class code example, Str class code example

  2. standard functions and lambda expressions:

    CallableObjects code example

  3. aliases:(C++11)
    using AliasName = TypeName;
    Equivalent to typedef except that types can be templates.

    Aliases code example

  4. uniform initialization:(C++11)
    T var { item };
    std::Container cont { item1, item2, ... };

    Here, std::Container could any STL container like std::vector<int> or std::list<std::string>.

    STL Containers code examples

  5. auto(C++11)
    auto is a type defined by the compiler, not the designer, using type inference. It requires initialization and guarantees no temporaries are created. The designer can override the compiler's inference as shown in the second and fourth lines below. In this case there may be temporaries created.

    auto var { item };
    auto var = T{ item };
    auto cont { item1, item2, ... };
    auto cont = std::Container{ item1, item2, ... };
  6. range-for:(C++11)
    range-for works with any container type that provides iterators and begin() and end() functions. This includes all the STL containers, std::array, and std::string. In the first line c is a copy of the next container element. In the second line c is a reference to the next container element and so can be used to modify that element's value.

    for(auto c : cont) { body }
    for(auto& c : cont) { body }
  7. nullptr:(C++11)
    nullptr is a replacement for 0 and NULL for initializing pointers. It is used to indicate that a pointer does not reference initialized memory. The language guarantees that deleting a nullptr does nothing.

    T* ptr = nullptr;
    unique_ptr<T> ptr(nullptr);
  8. constexpr:(C++11) - not implemented in Visual Studio 2013
    A constexpr is an expression or function that can be evaluated at compile-time.

    constexp sum = 1 + 2 + 3;
    constexp int accum(int n) { return n <= 1 ? 1 : accum(n-1); }
  9. decltype(T):(C++11)
    If the argument is the unparenthesised name of an object or function or is a member access expression, e.g., object.member or pointer->member then decltype specifies the declared type of T.

    If the argument is any other expression of type T then:
    • If the value category of T is xvalue then decltype specifies T&&
    • If the value category of T is lvalue then decltype specifies T&
    • Otherwise decltype specifies T
    auto l = [](args) opt[->R] { body };
    decltype(l) l2 = l;
  10. static_assert:(C++11)
    Performs compile-time assertion checking.
    static_assert(bool_constexpr, message)
  11. override and final:(C++11)
    override is an optional post-qualifier for virtual functions in a derived class. It causes compiler checking to verify that the function has exactly the same name and type sequence as a base class virtual function. This avoids the compiler treating a function (with spelling errors) as an overload instead of the override the designer intended.

    final is a post-qualifier that prohibits overriding qualified virtual member functions and using qualified classes as inherited bases.
  12. variadic templates:(C++11)
    Variadic templates support writing functions that take an arbitrary number of arguments.

    template <typename C, typename T, typename... Args> void inserter(C& c, T&& t, Args&&... args) { /* another body */ }
    template <typename c, typename t> void inserter(C& c, T&& t) { /* body */ }

    The first template function accepts an arbitrary finite number of moveable items of type T and processes the first one and calls itself recursively to handle the remainer. The second function is a template specialization that stops the recursion.

    The set of type parameters in a variadic template is referred to as a "Parameter Pack"

    Code Example, Reference

  13. noexcept: C++11

    noexcept is a specification that can be part of a function declarator.

    Void fun (int i) noexcept

    If the body of the function throws an unhandled exception std::terminate() is called by default.

  14. literals

    Literals are compile-time constants. The specifiers below allow us to be fairly specific about the literal type to avoid needing silent conversions when there is a compatible type mismatch in code expressions.

    type value interpretation
    integer literal 10 integer
    10u unsigned integer
    10l long integer
    10ul unsigned long integer
    floating literal 10.0 double precision float
    10.0f single precision float
    10.0l long double
    10.0e-2 0.1 using exponential notation
    string literal "a string" const char[]
    L"a string" const wchar_t[]
    u8"a string" const char[] with utf-8 encoding
    u"a string" const char16_t[] with utf-16 encoding
    U"a string" const char32_t[] with utf-32 encoding
    R"a string" const char[] with raw encoding => everything is a char including \ and markup

    C++14 will be introducing user defined literal suffixes, e.g. ns for nanosecond, kg for kilogram, etc.

New Library Features:
  1. New Containers:

    Here's a list of the most frequently used containers, annotated to show what was added in C++11. All the containers can be accessed with container specific iterators, e.g., vector<double>::iterator;

    Container Discussion
    std::vector<T> An indexable collection of items of type T stored in continguous memory.
    Constant time insertion at back, O(N) if inserted at front.
    std::list<T> A doubley linked list of items of type T. Constant time to store in front or back, but O(N) to insert in the middle.
    std::deque<T> An indexable collection of items of type T. Constant time to store in front or back, but O(N) to insert in the middle. This is a stringe beast composed of three blocks of contiguous memory, at the front, at the back, and in the middle.
    std::queue<T> A First In First Out (FIFO) collection of items of type T. Items are Enqueued on the front and Dequeued from the back. It is a wrapper around a std::deque<T> so it is constant time to Enqueue and Dequeue. I don't think you can access interior elements with an iterator but I'll have to check that to be sure.
    std::stack<T> A Last in First Out (LIFO) collection of items of type T. Constant time to push and pop elements. Same access comments as for the std::queue<T>
    std::set<Key> An ordered collecion of items of type T. The std::set<Key> is based on a balanced binary (Red-Black) tree, so operations are logrithmic, O(ln(N)) insertion, search, and retrieval. Sets will not accept duplicate keys.
    std::multiset<Key> An ordered collecion of items of type T. The std::multiset<Key> is based on a balanced binary (Red-Black) tree, so operations are logrithmic, O(ln(N)) insertion, search, and retrieval. multisets will accept duplicate keys but that makes search and retrieval more complex as you may get back a range of values for the duplicated key.
    std::map<Key, Value> An colletion of key-value pairs of types Key and Value, respectively, ordered on the keys. The std::map<Key, Value> is based on a balanced binary (Red-Black) tree, so operations are logrithmic, O(ln(N)) insertion, search, and retrieval. Maps will not accept duplicate keys. If you iterate over the collection you will get a sequence of pairs with iter->first returning the key and iter->second returning its associated value.
    std::multimap<Key, Value> An colletion of key-value pairs of types Key and Value, respectively, ordered on the keys. The std::map<Key, Value> is based on a balanced binary (Red-Black) tree, so operations are logrithmic, O(ln(N)) insertion, search, and retrieval. Multimaps will accept duplicate keys. The same comments we made about the std::map<Key, value> apply here. If you iterate over the collection you will get a sequence of pairs with iter->first returning the key and iter->second returning its associated value.
    std::unordered_set<Key>
    C++11
    An unordered colletion of items of Key type. The std::unordered_set<Key> is based on a hash table, so operations are are constant time for insertion, search, and retrieval. Unordered_sets will not accept duplicate keys. If you iterate over the collection you will items of type Key.
    std::unordered_multiset<Key>
    C++11
    An unordered colletion of keys. The std::unordered_multiset<Key> is based on a hash table, so operations are are constant time for insertion, search, and retrieval. Unordered_multisets will accept duplicate keys. If you iterate over the collection you will get a sequence of keys.
    std::unordered_map<Key, Value>
    C++11
    An unordered colletion of key-value pairs of types Key and Value, respectively. The std::map<Key, Value> is based on a hash table, so operations are are constant time for insertion, search, and retrieval. Unordered_maps will not accept duplicate keys. If you iterate over the collection you will get a sequence of pairs with iter->first returning the key and iter->second returning its associated value.
    std::unordered_multimap<Key, Value>
    C++11
    An unordered colletion of key-value pairs of types Key and Value, respectively. The std::map<Key, Value> is based on a hash table, so operations are are constant time for insertion, search, and retrieval. Unordered_maps will accept duplicate keys. If you iterate over the collection you will get a sequence of pairs with iter->first returning the key and iter->second returning its associated value.

    C++11 STL Container code examples, C++03 STL Container code examples

  2. Smart Pointers: C++11

    Smart pointers are instances of classes that wrap native pointers, keep the pointer syntax, but add additional operations.

    Declaration Discussion
    std::unique_ptr<T> uptr(new T); std::unique_ptr is a smart pointer that represents sole ownership of a resource created on the heap. Its action is to provide access to its owned object through standard pointer syntax and to delete the object when it goes out of scope.

    You must be careful not to initialize two or more std::unique_ptrs with the same raw pointer as that will cause delete to be called more than once on the owned object with undefined behavior.
    std::shared_ptr<T> sptr1(new T);
    std::shared_ptr<T> sptr2(sptr1);
    std::shared_ptr is a smart reference counted pointer that represents shared ownership of a resource created on the heap. When a shared pointer goes out of scope it decrements its reference count. Only if the count goes to zero is the resource deleted.

    You must be careful not to create more than one std::shared_ptr from a raw pointer. After the first is created you must create the remainder from an already defined std::shared_ptr sharing the same resource.
    std::weak_ptr<T> wptr = sptr1; std::weak_ptr allows you to refer to an object it doesn't own and may have been deleted. You check by calling wptr.lock() or wptr.expired().

    TestClass code example of std::unique_ptr

  3. type traits: C++11

    The type_traits library lets you make queries about a given type, like is it a pointer or is it a class. here's a complete list.

  4. chrono: C++11

    The chrono library has facilities for constructing clocks and measuring times. You can get the system time with std::system_clock and construct a high resolution timer from std::high_resolution_clock. here's a list of all its facilities.

    Chrono Timer code example
  5. initializer-list: C++11

    std::initializer-list is a class that supports initializing declared primitives, structs, classes, and containers with the values they will hold on startup. Here are two samples:

    int x { -5 };
    std::vector<int> vint { 1, 2, 3, 4 };

    You need to be careful when the type you are initializing has a constructor that takes a single parameter. If your syntax uses braces instead of parentheses, then the initializer list will be used rather than the constructor you intended.

  6. tuple: C++11

    std::tuple<T1, T2, ...> is a class that holds a fixed number of instances of arbitrary types. It is a generalization of std::pair<F, S>. the std::make_tuple(Args... args) is a variadic template function designed to make it easy to construct tuples. The non-member function std::get<n>(std::tuple) provides access to a tuple's nth member instance.

    tuple syntax Description
    std::tuple<T1, T2, ...> t { t1, t2, ...} Declare an instance of a tuple that holds instances of T1, T2, ...
    Tn tn = get<n>(t); Retrieve the value of the nth element of the tuple t.
    std::tuple<T1, T2, ...> t = std::make_tuple<t1, t2, ...> Alternate way to initialize a std::tuple.

  7. regex: C++11

    Regular Expressions are strings with a particular syntax that makes it easy to specify exactly what a search should match. There are special characters for the beginning and end of a search string, ways to specify that any of a set of characters are acceptable at some place in the string and so forth. The standard C++ library now has std::regex, a regular expression processor that you may find useful.

    here's a tutorial. You will also find a nice expositions in "The C++ Programming Language" starting on page 1051 and in "The C++ Standard Library" starting on page 717. These are our two required texts.

  8. concurrency: C++11

    C++ now supports threads and synchronization constructs to support multi-threaded programming. Here are links to C++11concurrency examples and a blocking queue implementation that we will discuss later in the semester. I recommend that you wait awhile before looking at these. You will need to be quite comfortable with C++11 to get much out of the examples.

  9. algorithms: C++11

    There have been a number of relatively useful algorithms in the standard library. The table below lists a few of the ones I use occasionally. I've also included several that have been added with the new C++11 standard.

    Note that all of the STL algorithms treat [start_iter, end_iter) as a closed open interval. That is, start_iter points to the first element processed and end_iter points to one past the last element processed.

    Algorithm Discussion
    bool std::all_of(start_iter, end_iter, PredicateFunctor());
    C++11
    Checks if a predicate functor returns true on all of the elements of a container.
    bool std::any_of(start_iter, end_iter, PredicateFunctor());
    C++11
    Checks if a predicate functor returns true on any of the elements of a container.
    bool std::none_of(start_iter, end_iter, PredicateFunctor());
    C++11
    Checks if a predicate functor returns false on all of the elements of a container.
    UnaryFunction std::for_each(start_iter, end_iter, UnaryFunction f) Functior processing is called on each element of the container.
    found_iter std::find(start_iter, end_iter, T& t); returns an iterator pointing to the found item or end_iter.

    Code example using for_each near the end of the source code.

CST strip