You are on page 1of 82

C++11

Introduction to the New Standard

Alejandro Cabrera
February 1, 2012
Florida State University
Department of Computer Science
Overview
A Brief History of C++
Features Improving:
Overall Use
Meta-programming
Resource-critical/High-performance Programming
Class and Object-Oriented Design
New Libraries
How to Use it Today
A Brief History
C With Classes C++ v2.0
C++98
Boost C++ Libraries
C++03 and C++TR1
C++11
C With Classes (1979)
Started as a result of Ph.D. thesis work of
Bjarne Stroustrup
Added to C:
Classes
Derived classes
Strong type checking
Inlining
Default function arguments
C++ v 1.0 (1983)
Added to C With Classes:
Virtual functions
Function name and operator overloading
References
Constants
User-controlled, free-store memory control
Improved type checking
Single-line comments
The C++ Programming Language 1e published
(1985)
C++ v 2.0 (1989)
The C++ Programming Language 2e
published (1991)
Added to C++ v 1.0: Late additions:
Multiple inheritance Templates
Abstract classes Exceptions
Static member functions Namespaces
const member functions New-style casts
Protected members
Boolean type
C++ 98 (1998)
C++ is standardized (ISO/IEC 14882:1998)
Standard includes language core and standard
library
Standard library includes C library, containers,
I/O streams, and much more
Boost C++ Libraries (199x)
The Boost C++ libraries provide portable,
efficient implementations of many C++ library
components
Often times, libraries that appear in later
standards make their debut in Boost
Boost releases go back as far as 1999
For more information, visit:
http://www.boost.org/
C++ 03 (2003)
Correction to C++ standard is published
(ISO/IEC 14882:2003)
TR1, an extension to the standard library, was
also published around this time (2005)
TR1 is only a draft, not a standard
Most features detailed in TR1 became part of 2011
standard
C++ 11 (2011)
Unanimously approved by C++ committee in
August 2011
C++11 brings many new features, many that
make it more apparent that C++ is a hybrid
language
This presentation will cover most of the new
features in detail
History
Summary
Early C++ - 1979 1998
C++, first standard 1998
Birth of Boost C++ Libraries - 1999
C++, corrected standard 2003
C++ TR1 2005
C++11 2011
C++ TR2 W.I.P.
Features Overview
Easier programming
Easier meta-programming
Facilitated, performance-critical programming
Better class design
Easier Programming
Introduction
C++11 introduces:
new keywords
new constructs
fixes parsing issues
adds support for garbage collection
I'll demonstrate how this leads to easier
programming
Easier Programming
auto keyword
auto is not a new keyword in C++
auto used to declare a given variable as a local
variable
Now, auto is used to have the compiler perform
type-inference for you
Easier Programming
auto keyword
Uses of auto:
Simplify iterator use in iteration constructs
Simplify type declarations in meta-programming
contexts
For more examples, refer to: auto.cpp
auto also meshes well with the new range-for
loop!
Easier Programming
enum class
Old-style enumerations have three problems:
they implicitly covert to integers
they are globally visible, introducing name-clashing
the underlying type cannot be declared:
introducing compatibility problems
cannot be forward declared
Easier Programming
enum class
While old-style enums are still supported, new-
style enums address all their weaknesses:
Using an enum class variable where an integer is
expected raises a compiler error:
Explicit cast required
Scope of enum class declaration is limited to scope
of declaration
Underlying type can be specified
For examples, refer to: enum_class.cpp
Easier Programming
constexpr keyword
For initializing complicated constants, sometimes
functions are desired
For example, initializing the size of a static buffer that
depends on:
Number of CPUs available on system
Amount of memory available on system
Speed of CPUs on system
Maximum stack-size on system
However, functions cannot be used to accomplish this in
C or C++ - macros must be used
Macros are not type-safe
Easier Programming
constexpr keyword
Introducing constexpr:
Used to provide compile-time expressions
Can be used with user-defined types
Guarantees initialization at compile-time
Used as a function qualifier before the
function's return type
Also allows for more extensive compiler-
optimization opportunities!
For more details, refer to: constexpr.cpp
Easier Programming
nullptr keyword
Minor syntactic sugar improvement
Previous efforts to define a clear use of null
revolved around macros
#define NULL ((void *) 0)
Now, nullptr can be used to express null-pointer
initialization where that is the intent.
For more details, refer to: nullptr.cpp
Easier Programming
range-for Loop Construct
Major syntactic sugar upgrade
Provides a for loop similar to for-each loop
provided in other high-level languages
Can be used on any sequence for which a
begin() and end() function are defined!
Especially useful for sequential one-pass
algorithms and function applications
For more details, refer to: rangefor.cpp
Easier Programming
Initializer Lists
Initializer lists allow the construction of any type
using a curly-brace enclosed, comma-separated
list of elements
Previously, this style of construction was limited to
primitive arrays with unspecified size
Especially useful for providing easier to use
interfaces for container types
Critical for the support of a new feature, unified
initialization
For more details, refer to: ilist.cpp
Easier Programming
Unified Initialization
Currently, there are many ways to initialize
C:
X a = {v}; // structs, arrays
X a = v; // primitives
C++:
new X(v); // heap allocation
X a(v); // for classes with constructors
X(v); // temporaries
X(v); // functional-style casts
Easier Programming
Unified Initialization
The problem is, looking at a huge code base, it's
impossible to tell just by looking if X(v) is a casting
operation or a construction
Solution: unified initialization
X v{1, 2, 3};
vector<int> vec{1,2,3,4};
float *f{new float[10]};
int three{3};
ShadingMode shade{ShadingMode::SMOOTH};
For more details, refer to: unified_initialization.cpp
Easier Programming
Right-Angle Bracket Parse Fix
C++98/03 syntax specification did not account for:
vector<vector<int>> x;
Frequently, this was interpreted as either a right
shift operation or input operator
C++98/03 solution:
vector<vector<int> > x; // space them out
C++11 fixes this.
An example is provided: right_bracket_parse.cpp
Easier Programming
Improved POD Rules
POD: Plain Old Data type, a.k.a., standard layout
types
Allows an object to be initialized using memcpy, and
serialized/loaded using read/write directly
An important concept for serialization and optimization
C++98/03 only considered objects avoiding use of
certain language features PODs
Cannot use virtual functions
Cannot have constructor/destructor
Cannot allocate memory on heap
Easier Programming
Improved POD Rules
C++11 expands set of objects considered PODs:
Recursively, if all members are PODs, so is the whole
No virtual functions
No virtual bases
No references
No multiple access specifiers (protected, public, private)
The biggest addition is that POD types may now
have constructors/destructors
For more details, refer to: improved_pod.cpp
Similar improvements have been made for unions!
Easier Programming
Long Longs
Guarantees availability of [unsigned] long long
type
See long_long.cpp
Easier Programming
User-Defined Literals
Various literal types have built-in support
12 // int
'a' // char
as // null-terminated string
1.2f // float
1.2lf // double
0xD0 // hexadecimal
However, there is no support for literals of user-defined
types
123s // seconds?
hello!s // std::string
Easier Programming
User-Defined Literals
C++11 introduces literal operators to create
user-defined literals
By overloading a single function, one can
create literals with a given suffix for:
integers
floats
strings
characters
Easier Programming
User-Defined Literals
This is extremely useful for creating Domain-
Specific Languages (DSLs), or say,
implementing a unit system
25.1s // seconds
12.5mps // meters per seconds
Distance m = 12.5mps * 25.1s
For more details, refer to:
user_defined_literals.cpp
Requires GCC 4.7 (svn trunk, unreleased)
Easier Programming
Raw Strings
C++98 provides no means to escape strings for
use with regular expression engines
Language escaping rules get in the way of correctly
writing regular expressions
Example: match all lines containing two words
separated by a backslash
Solution: \\w\\\\\\w
C++11 makes this much easier by providing
raw strings.
Easier Programming
Raw Strings
Again, with raw strings:
Solution: R(\w\\\w)
More examples:
Quoted string: R(quoted string)
Regex: R([\d\d\d]{3})
Even the delimiter pair () is only a default:
Parenthetical string: R*((Tough cookie.))*
Delimiter string is this color to ease reading
For more examples, see: raw_strings.cpp
Easier Programming
Lambda Functions
In C++, to work with the standard algorithms
library, one often had to create function objects
For example, to count all elements less than 5:
1. Create a function object LessThan returns true if
an input argument is less than 5
2.Pass LessThan to count_if as the final parameter.
Easier Programming
Lambda Functions
This has a few undesirable consequences
LessThan potentially pollutes the global namespace
Furthermore, function objects created at non-global
scope cannot be used as template arguments
To implement simple logic, an entire class had to be
implemented (~5 LOC for easy cases)
Lambdas were created to address these
problems
Easier Programming
Lambda Functions
Lambdas are anonymous, shorthand function
objects
Note: C++11 did not invent lambdas. They
appear in many modern languages, including:
Haskell, Python, C#,
Easier Programming
Structure of Lambda Functions
C++11 lambdas have a structure that takes
some getting used to
The capture list
(optionally) The argument list [same as function
argument list]
The function body
(optionally) The return type using suffix return type
syntax
Only if the return type cannot be deduced, which is true
most of the time for function bodies longer than a single
statement
Easier Programming
Lambda Functions: Capture List
It can take on a few forms:
[] take none of the variables from the enclosing
scope
[&] take all the variables from the enclosing scope
by reference
[=] take all the variables from the enclosing scope
by value
There is also support for capture-by-name, to
capture only part of the enclosing scope
Easier Programming
Lambda Functions: Return Type
C++11 introduces a new way to specify return
types that apply for the decltype keyword and
for lambdas: suffix return style
In a simple lambda, it looks like:

[] (int a, int b) -> bool { return a < b; }
For many examples, refer to: lambda.cpp
Easier Programming
Lambda Functions: Advice
Benefits:
Concise, terse
Does not pollute namespace
Great for one- or two-liners
Cons:
Less readable intent may not be clear
Can easily create obfuscated code!
Capturing entire enclosing scope by value can be very expensive
be careful!
Keep in mind that C++11 now allows local-types as template
arguments
A local, function object class may be the best solution!
Easier Programming
Generalized Attributes
Crafted as an attempt to unify various compiler-
specific extensions
Generalized attributes will not be discussed
further in this presentation, as support is nearly
non-existent
For further information:
Generalized Attributes ISO/IEC Paper
Easier Programming
Garbage Collection
Garbage collection serves as a means to
automatically clean up heap memory that cannot
be reached
Support for this has been experimental for a long
time in C/C++
The standard now makes provisions for adding
support if a compiler wishes to implement garbage
collection
For more details, see:
GC ISO/IEC Paper
Easier Programming
Summary
New keywords
auto, enum class, constexpr, nullptr
New constructs
range for-loop, initializer lists, unified initialization
Language fixes
Right-angle bracket parse
Improved usability
Less restrictive unions and PODs, long longs, user-defined
literals, raw strings, lambdas, generalized attributes, enum
class, local types as template args
Support for garbage collection
Easier Meta-programming
Introduction
Meta-programming and related techniques
allow for entire libraries of highly-optimized,
highly-customizable software to be generated
from a limited source base
Meta-programming also adds new ways to
compose classes and functions
C++11 adds a few features to facilitate meta-
programming
Easier Meta-programming
Overview
decltype
constexpr
static_assert
variadic templates
<type_traits> library
Easier Meta-programming
decltype keyword
decltype used in conjunction with the new return type
syntax can facilitate template programs
Consider:
template <class T, class U>
??? mul(T x, U y)
{
return x * y;
}
What is the return type? (assuming operator*(x,y) is
defined)
Easier Meta-programming
decltype keyword
Here is the solution using C++11:
template <class T, class U>
auto (T x, U y) -> decltype(x*y)
{
return x * y;
}

decltype expressions are evaluated at compile-time


No examples are provided for decltype
Easier Meta-programming
static_assert keyword
static_assert is extremely valuable for placing
compile-time constraints on template-
parameters
For example, in combination with the new
type_traits library, one could...:
Allow only integral parameters using is_integer
Allow only values of N less than 16 for Factorial<N>
Allow only POD types for MakePacket<PType>
For an example, refer to: static_assert.cpp
Easier Meta-programming
Variadic Templates
One of the features behind some of the most
amazing wizardry that goes on in meta-
template programming
Previously, recursive template instantiation was
required to emulate type-lists
Could get very expensive for compiler
Variadic templates essentially allow recursion to
be replaced by iteration
Easier Meta-programming
Variadic Templates
Two components:
Declaration
template <typename T, typename... Args>
void printf(const char *format, T value,
Args... args);
Iteration
Uses either iteration over run-time arguments or iteration over
compile-time size of Args parameter pack
In latter case, uses sizeof...() operator on Args
For more information, search for <tuple>
implementation inside your compiler source.
Easier Meta-programming
<type_traits> Library
Provides various utilities to assist with meta-
programming
Used primarily to ask questions about a type:
Is type T integral?
Is type T default constructible?
Does type T have a particular operator defined?
Easier Meta-programming
Summary
decltype return type inference
constexpr generalized compile-time
expressions
static_assert compile-time constraints
variadic templates more efficient and usable
template instantiation
Efficient Programming
Introduction
C++11 was designed with efficiency in mind
A few features were added to the language to
enable more efficient implementations of
various familiar operations
Perhaps the most significant feature added in
this regard is the rvalue reference, that enables
perfect forwarding
This feature and more will be explained over
the next few slides
Efficient Programming
Overview
std::move and rvalue references
noexcept expression
alignment support
alignas
alignof
Efficient Programming
rvalue references
An rvalue is any temporary that occurs on the
right side of an assignment
As compared to lvalues, which are storage
locations on the left side of an assignment
C++11 brings rvalue references, denoted by a
type signature of T&&
These are meant to be used in conjunction with
the std::move function
Efficient Programming
std::move Function
std::move takes as an argument any one type
and returns an rvalue reference of that type
Does not trigger copy constructor
This is very useful for:
Implementing move constructors
Implementing swap operations
Efficient Programming
Move: What Does it Mean?
A move operation is intended to be a destructive copy
Instead of copying data over, move implemented correctly...
Assigns the address of source pointers to destination pointers
Copies over primitive values
Sets source pointers to nullptr
Either ignores source primitive values or sets them to 0
Since all pointers in the source are set to nullptr, they are not
destructed
This allows the execution of a technique known as perfect
function forwarding
Efficient Programming
Perfect Function Forwarding
A move operation is intended to be a destructive copy
Instead of copying data over, move implemented correctly...
Assigns the address of source pointers to destination pointers
Copies over primitive values
Sets source pointers to nullptr
Either ignores source primitive values or sets them to 0
Since all pointers in the source are set to nullptr, they are not
destructed
This allows the execution of a technique known as perfect function
forwarding
Very useful for factory functions, in particular
For more details, refer to:
C++ Rvalue References Explained
Efficient Programming
noexcept Expression
Declares to the compiler that a given function will
NEVER propagate an exception
A function declared as noexcept that encounters an
exception will immediately terminate the program
Allows the compiler to optimize those functions better
Actual form is:
function_type
name(...) noexcept[(expression)]
{
}
Efficient Programming
noexcept Expression
By default, it occurs as noexcept(true), and is
used as noexcept
If the expression given in the parentheses can
throw, then noexcept is disabled
Allows for flexible conditional enabling of the
noexcept feature
Very important for generic programming!
Efficient Programming
noexcept Suggestions
The following are great functions to decorate
with noexcept:
Destructors these should never throw
Move constructors
Functions that were not designed to handle
exceptions
noexcept serves as both an indicator to the compiler and
documentation for humans!
For more details, refer to: noexcept.cpp
Efficient Programming
Alignment Support
Discussion of this feature will be limited as support for it is
currently very limited
Two new operators are added to C++:
alignas
alignof
alignas allows for a memory region to be aligned on a
specified boundary
alignas(double) unsigned char c[1024];
alignas(16) float[100];
alignof returns the alignment of a give type
const size_t n = alignof(float);
Efficient Programming
Summary
rvalue references
Enable perfect forwarding, expressed as T&&
std::move
Function that performs a move operation
noexcept expression
Guarantees a function will not throw an exception
alignment support
alignas, alignof Particularly relevant for
serialization and SIMD programming
Class Design
Introduction
Good class design is fundamental for making the most of C++
C++11 adds several features that target the realm of classes
Some of these facilitate the implementation, some
assist/enforce the interface
Some particularly salient features include:
Delegating constructors
Constructor control
Non-static member initialization
These features and more are covered in the following slides
Class Design
Overview
Controlling defaults:
default and delete
New constructors: move and initializer list constructor,
move assignment
Delegating constructors
Inheriting constructors
Non-static member initialization
Inheritance control: override, final
Explicit conversion operators
Inline name spaces for version support
Class Design
Controlling Silent Defaults
The compiler has always silently generated
various class members if any one of them is
defined
Constructor: Default and copy
Destructor
Copy assignment
Sometimes, you don't want to allow copying of
a resource
Class Design
Controlling Silent Defaults
C++98/03 solution:
Declare class NonCopyable with private copy
assignment and copy constructor
Have new class publicly inherit from NonCopyable
C++11 solution:
class X {
X(const X&) = delete;
const X& operator=(const X&) = delete;
};
Class Design
Controlling Silent Defaults
C++11 also allows you to communicate whether
a default member is used:
class X {
X() = default;
~X() = default;
};
For more details, refer to: class_control.cpp
Class Design
New Constructors
C++11 gives you access to two new types of
constructors:
Initializer list constructor
Move constructor
Move assignment operator
The first can be used to provide convenient use of
your class
The latter two are important to avoid unnecessary
memory copying
Implementation examples are given in: move.cpp
Class Design
Delegating Constructors
Many modern OO languages allow you to
implement other constructors in terms of one
constructor
C++98/03 does not
Beginning with C++11, this is now possible!
For details, refer to: delegating_constructor.cpp
Support requires GCC >= 4.7
Class Design
Inheriting Constructors
Allows members available in base class to be
used in derived class
Not currently supported by any compiler
For details, refer to: inheriting_constructors.cpp
Class Design
Non-static Member Initialization
Previously, it was a compilation error to give
default values to non-static class members
C++11 makes this possible using the new
initialization syntax
Allows for simplified constructors
For details, refer to: member_defaults.cpp
Support requires GCC >= 4.7
Class Design
Inheritance Control
C++11 introduces two new keywords for constraining
designs through inheritance
final
Prevent virtual function from being overriden.
override
Used to clearly express the intent that a given derived class
function is meant to provide a new implementation for a base
class function
Helps the compiler flag errors where one accidentally overloads
rather than overrides
For more details, refer to: inheritance_control.cpp
Class Design
Explicit Conversion
Allows the use of the explicit keyword in
conversion operators now
Disables conversion in implicit context, if that is the
desired result
This feature has a limited range of use
It primarily targets the case where you want to only
allow conversion from one class to another during
construction, but not in function call or copy
contexts
For details, refer to: explicit_conversion.cpp
Class Design
Inline Namespaces
Used primarily to provide version control within
the language
Rules:
Can only be used within an enclosing namespace
To reference elements of inline namespace, need
only use name of enclosing namespace
Inline namespace is invisible to external code
For examples, refer to: inline_namespace.cpp
Class Design
Summary
Improvements to constructors
Ability to control available constructors, new move
and initializer list constructors, delegating
constructors, inheriting constructors
Additional improvements:
Non-static member initialization, ability to control
inheritance, explicit conversion operators, inline
namespaces
New Libraries
New containers:
<unordered_*> - hash-implemented [multi]sets and [multi]maps
<forward_list> singly-linked list
<array> compile-time-sized array class
<tuple> type container
Concurrency support:
threads, mutexes, locks, condition variables, promises, futures, atomics
Random number generators <random>
Regular expressions <regex>
Compile-time rational arithmetic <ratio>
Smart pointers <memory>
Time management <chrono>
For examples, refer to: libraries/*.cpp
Using C++11 Now
C++11 depends on the availability of a fairly recent
compiler
Standard draft was published in early 2011, final draft in
August 2011.
GCC >= 4.6, LLVM Clang >= 3.0, MSVC >= 11.0
In many cases, the feature that you hope to use is
available on only GCC and/or LLVM Clang
For a few features, no compiler implements them
If your goal is portability across compilers, DO NOT use
C++11
C++`11 is not available on linprog
Using C++11 Now
Compiler support
Features lacking support
Using C++11 Now
Compiler Support
GCC C++11 Page
Apache Compiler Support Matrix
Clang LLVM C++11 Support
Intel Compiler C++11 Support
Visual Studio C++11 Compiler Support
Using C++11 Now
Features Lacking Support
The following is a list of features that no or almost no compiler supports:
alignas (Clang 3.0)
alignof (GCC 4.5, Clang 2.9)
constexpr (GCC 4.6, Clang 3.1)
Initializer Lists (GCC 4.4)
Raw-string Literals (GCC 4.5, Clang All)
Template alias (GCC 4.7, Clang 3.0, MSVC 12.1)
Unrestricted unions (GCC 4.6, Clang 3.0)
Range-for loop (GCC 4.6, Clang 3.0)
Generalized attributes (MSVC 12.1 )
Non-static member initialization (GCC 4.7, Clang 3.0)
In short, if you want the most salient C++11 features now, use GCC
If portability is important, use Boost C++11 emulation layers
#include <iostream>
#include <string>
using namespace std;

int main()
{
string msg = R(Thanks!);

for (auto x : msg)


cout << x;

cout << endl;

return 0;
}

You might also like