Feb 1, 2012 ... C++11. Introduction to the New Standard. Alejandro Cabrera. February 1 ... C++
98. ○ Boost C++ Libraries. ○ C++03 and C++TR1. ○ C++11 ...
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
●
●
Static member functions
Exceptions
●
Namespaces
●
New-style casts
●
Boolean type
● ●
const member functions Protected members
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, newstyle 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 compileroptimization 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 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 x;
Frequently, this was interpreted as either a right shift operation or input operator C++98/03 solution: ●
vector 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 DomainSpecific 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 ●
●
Example: match all lines containing two words separated by a backslash ●
●
Language escaping rules get in the way of correctly writing regular expressions
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 compilerspecific 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 ●
●
New constructs ●
●
Right-angle bracket parse
Improved usability ●
●
range for-loop, initializer lists, unified initialization
Language fixes ●
●
auto, enum class, constexpr, nullptr
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 metaprogramming
Easier Meta-programming Overview ●
decltype
●
constexpr
●
static_assert
●
variadic templates
●
library
Easier Meta-programming decltype keyword ●
decltype used in conjunction with the new return type syntax can facilitate template programs
Consider: template ●
??? 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 ●
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 templateparameters 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
●
Allow only POD types for MakePacket
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 metatemplate 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 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 implementation inside your compiler source.
Easier Meta-programming Library ●
●
Provides various utilities to assist with metaprogramming 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 ●
●
std::move ●
●
Function that performs a move operation
noexcept expression ●
●
Enable perfect forwarding, expressed as T&&
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 –
●
override –
–
●
Prevent virtual function from being overriden. 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 ●
●
This feature has a limited range of use ●
●
Disables conversion in implicit context, if that is the desired result 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: ●
- hash-implemented [multi]sets and [multi]maps
●
– singly-linked list
●
– compile-time-sized array class
●
– type container
Concurrency support: ●
threads, mutexes, locks, condition variables, promises, futures, atomics
●
Random number generators
●
Regular expressions
●
Compile-time rational arithmetic
●
Smart pointers
●
Time management
●
For examples, refer to: libraries/*.cpp
Using C++11 Now ●
C++11 depends on the availability of a fairly recent compiler ●
●
●
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 ●
●
Standard draft was published in early 2011, final draft in August 2011.
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 #include using namespace std; int main() { string msg = R”(“Thanks!”)”; for (auto x : msg) cout