C++11 - the new ISO C++ standard

Modified August 19, 2016

This document is written by and maintained by Bjarne Stroustrup. Constructive comments, corrections, references, and suggestions are of course most welcome. Currently, I'm working to improve completeness and clean up the references.

Translations:

I have contributed to the new, unified, isocpp.org C++ FAQ maintained by The C++ Foundation of which I am a director. The maintenance of this FAQ is likely to become increasingly sporatic.

C++11 is the ISO C++ standard ratified in 2011. The previous standard is often referred to as C++98 or C++03; the differences between C++98 and C++03 are so few and so technical that they ought not concern users.

A late working paper is available. This is close to the final draft international standard formally accepted by a 21-0 national vote in August 2011.

Before its official ratification, we called the upcoming standard C++0x. I have not had the time to update the name consistently, sorry, and anyway I like the name C++0x :-). The name "C++0x" is a relict of the days where I and others, hoped for a C++08 or C++09. Think of 'x' as hexadecimal (i.e., C++0B == C++11).

All official documents relating to C++11/C++0x can be found at the ISO C++ committee's website. The official name of the committee is SC22 WG21.

Caveat: This FAQ will be under construction for quite a while. Comments, questions, references, corrections, and suggestions welcome.

Purpose

To give an overview of the new facilities (language features and standard libraries) offered by C++11 in addition to what is provided by the previous version of the ISO C++ standard.

To give an idea of the aims of the ISO C++ standards effort.

To present a user's view of the new facilities

To provide references to allow for a more in depth study of features.

To name many of the individuals who contributed (mostly as authors of the reports they wrote for the committee). The standard is not written by a faceless organization.

Lists of questions

Here are some high-level questions

Questions about individual language features can be found here:

Questions about individual standard library facilities can be found here:

Below are answers to specific questions as indexed above.

What do you think of C++11?

My ideal is to use programming language facilities to help programmers think differently about system design and implementation. I think C++11 can do that - and do it not just for C++ programmers but for programmers used to a variety of modern programming languages in the general and very broad area of systems programming.

In other words, I'm still an optimist.

When will C++11 be a formal standard?

Following convention, the new standard is called C++11 (because it was published in 2011). Personally, I prefer plain C++ and to use a year marker only when I need to distinguish it from previous versions of C++, such as ARM C++, C++98 and C++03. For a transition period, I still use C++0x in places. Think of 'x' as hexadecimal.

When will compilers implement C++11?

I expect more and more features to become available with each new release. I expect to see the first complete C++11 compiler sometime in 2012, but I do not care to guess when such a compiler ships or when every compiler will provide all of C++11. I note that every C++11 feature has already been implemented by someone somewhere so there is implementation experience available for implementers to rely on.

Here are links to C++11 information from purveyors:

When will the new standard libraries be available?

What new language features does C++11 provide?

To try to select rationally from the flood of suggestions we devised a set of specific design aims. We couldn't completely follow them and they weren't sufficiently complete to guide the committee in every detail (and IMO couldn't possible be that complete).

The result has been a language with greatly improved abstraction mechanisms. The range of abstractions that C++ can express elegantly, flexibly, and at zero costs compared to hand-crafted specialized code has greatly increased. When we say "abstraction" people often just think "classes" or "objects." C++11 goes far beyond that: The range of user-defined types that can be cleanly and safely expressed has grown with the addition of features such as initializer-lists, uniform initialization, template aliases, rvalue references, defaulted and deleted functions, and variadic templates. Their implementation eased with features, such as auto, inherited constructors, and decltype. These enhancements are sufficient to make C++11 feel like a new language.

For a list of accepted language features, see the feature list

What new standard libraries does C++11 provide?

For a list of accepted libraries, see the library component list.

What were the aims of the C++11 effort?

is a better C

supports data abstraction

supports object-oriented programming

supports generic programming

Make C++ a better language for systems programming and library building -- that is, to build directly on C++'s contributions to programming, rather than providing specialized facilities for a particular sub-community (e.g. numeric computation or Windows-style application development).

Make C++ easier to teach and learn -- through increased uniformity, stronger guarantees, and facilities supportive of novices (there will always be more novices than experts).

For more details see:

What specific design aims guided the committee?

Maintain stability and compatibility -- don't break old code, and if you absolutely must, don't break it quietly.

Prefer libraries to language extensions -- an ideal at which the committee wasn't all that successful; too many people in the committee and elsewhere prefer "real language features."

Prefer generality to specialization -- focus on improving the abstraction mechanisms (classes, templates, etc.).

Support both experts and novices -- novices can be helped by better libraries and through more general rules; experts need general and efficient features.

Increase type safety -- primarily though facilities that allow programmers to avoid type-unsafe features.

Improve performance and ability to work directly with hardware -- make C++ even better for embedded systems programming and high-performance computation.

Fit into the real world -- consider tool chains, implementation cost, transition problems, ABI issues, teaching and learning, etc.

Another way of looking at detailed aims is to look at areas of use and styles of usage:

Where can I find the committee papers?

Core (CWG) -- dealing with language-technical issues and formulation

Evolution (EWG) -- dealing with language feature proposals and issues crossing the language/library boundary

Library (LWG) -- dealing with library facility proposals

Where can I find academic and technical papers about C++11?

Where else can I read about C++11?

Are there any videos about C++11?

Yes:

Is C++11 hard to learn?

Generalization: Replace, say, three rules with one more general rule (e.g., uniform initialization, inheriting constructors, and threads).

Simpler alternatives: Provide new facilities that are easier to use than their older alternatives (e.g., the array, auto, range-for statement, and regex).

How does the committee operate?

Many countries have national standards bodies with active C++ groups. These groups hold meetings, coordinate over the web, and some send representatives to the ISO meetings. Canada, France, Germany, Switzerland, UK, and USA are present at most meetings. Denmark, the Netherlands, Japan, Norway, Spain, and others are represented in person less frequently.

Much of the work goes on in-between meetings over the web and the results are recorded as numbered committee papers on the WG21 website.

The committee meets two to three times a year for a week each time. Most work at those meetings are in sub-working groups, such as "Core", "Library", "Evolution", and "Concurrency." As needed, there are also in-between meetings of ad-hoc working groups on specific urgent topics, such as "concepts" and "memory model." Voting takes place at the main meetings. First, working groups hold "straw votes" to see if an issue is ready for presentation to the committee as a whole. Then, the committee as a whole votes (one member one vote) and if something is accepted the nations vote. We take great care that we do not get into a situation where the majority present and the nations disagrees -- proceeding if that is the case would guarantee long-term controversy. Final votes on official drafts are done by mail by the national standards bodies.

The committee has formal liaison with the C standards group (SC22 WG14) and POSIX, and more or less formal contacts with several other groups.

Who is on the committee?

Naturally, many (but not all) of these volunteers have day jobs focused on C++: We have compiler writers, tool builders, library writers, application builders (too few of those), researchers (only a few), consultants, test-suite builders, and more.

Here is a very abbreviated list of organizations involved: Adobe, Apple, Boost, Bloomberg, EDG, Google, HP, IBM, Intel, Microsoft, Red Hat, Sun.

Here is a short list of names of members who you may have encountered in the literature or on the web: Dave Abrahams, Matt Austern, Pete Becker, Hans Boehm, Steve Clamage, Lawrence Crowl, Beman Dawes, Francis Glassborow, Doug Gregor, Pablo Halpern, Howard Hinnant, Jaakko Jarvi, John Lakos, Alisdair Meredith, Jens Maurer, Jason Merrill, Sean Parent, P.J. Plauger, Tom Plum, Gabriel Dos Reis, Bjarne Stroustrup, Herb Sutter, David Vandevoorde, Michael Wong. Apologies to the 200+ current and past members that I couldn't list. Also, please note the author lists on the various papers: a standard is written by (many) individuals, not by an anonymous committee.

You can get a better impression of the breath and depth of expertise involved by examining the author lists on the WG21 papers, but please remember there are major contributors to the standards effort who do not write a lot.

Will there be a C++1y?

What happened to "concepts"?

A radically simplified version ``concepts lite'' will be part of C++14 (as a technical report).

I have not deleted the concept sections from this document, but left them at the end:

Are there any features you don't like?

__cplusplus

auto -- deduction of a type from an initializer

auto x = 7;

auto x = expression;

The use of auto to deduce the type of a variable from its initializer is obviously most useful when that type is either hard to know exactly or hard to write. Consider:

template<class T> void printall(const vector<T>& v) { for (auto p = v.begin(); p!=v.end(); ++p) cout << *p << "

"; }

template<class T> void printall(const vector<T>& v) { for (typename vector<T>::const_iterator p = v.begin(); p!=v.end(); ++p) cout << *p << "

"; }

When the type of a variable depends critically on template argument it can be really hard to write code without auto. For example:

template<class T, class U> void multiply(const vector<T>& vt, const vector<U>& vu) { // ... auto tmp = vt[i]*vu[i]; // ... }

The auto feature has the distinction to be the earliest to be suggested and implemented: I had it working in my Cfront implementation in early 1984, but was forced to take it out because of C compatibility problems. Those compatibility problems disappeared when C++98 and C99 accepted the removal of "implicit int"; that is, both languages require every variable and function to be defined with an explicit type. The old meaning of auto ("this is a local variable") is now illegal. Several committee members trawled through millions of lines of code finding only a handful of uses -- and most of those were in test suites or appeared to be bugs.

Being primarily a facility to simplify notation in code, auto does not affect the standard library specification.

See also

the C++ draft section 7.1.6.2, 7.1.6.4, 8.3.5 (for return types)

[N1984=06-0054] Jaakko Jarvi, Bjarne Stroustrup, and Gabriel Dos Reis: Deducing the type of variable from its initializer expression (revision 4).

Range-for statement

void f(vector<double>& v) { for (auto x : v) cout << x << '

'; for (auto& x : v) ++x; // using a reference to allow us to change the value }

for (const auto x : { 1,2,3,5,8,13,21,34 }) cout << x << '

';

See also

right-angle brackets

list<vector<string>> lvs;

Why was this ever a problem? A compiler front-end is organized parses/stages. This is about the simplest model:

lexical analysis (make up tokens from characters)

syntax analysis (check the grammar)

type checking (find the type of names and expressions)

See also

the C++ draft section ???

[N1757==05-0017] Daveed Vandevoorde: revised right angle brackets proposal (revision 2).

control of defaults: default and delete

class X { // ... X& operator=(const X&) = delete; // Disallow copying X(const X&) = delete; };

class Y { // ... Y& operator=(const Y&) = default; // default copy semantics Y(const Y&) = default; };

The "default" mechanism can be used for any function that has a default. The "delete" mechanism can be used for any function. For example, we can eliminate an undesired conversion like this:

struct Z { // ... Z(long long); // can initialize with an long long Z(long) = delete; // but not anything less };

See also

control of defaults: move and copy

copy assignment

copy constructor

move assignment

move constructor

destructor

If any move, copy, or destructor is explicitly specified (declared, defined, =default, or =delete) by the user, no move is generated by default. If any move, copy, or destructor is explicitly specified (declared, defined, =default, or =delete) by the user, any undeclared copy operations are generated by default, but this is deprecated, so don't rely on that. For example: class X1 { X1& operator=(const X1&) = delete; // Disallow copying }; This implicitly also disallows moving of X1s. Copy initialization is allowed, but deprecated. class X2 { X2& operator=(const X2&) = delete; }; This implicitly also disallows moving of X2s. Copy initialization is allowed, but deprecated. class X3 { X3& operator=(X3&&) = delete; // Disallow moving }; This implicitly also disallows copying of X3s. class X4 { ~X4() = delete; // Disallow destruction }; This implicitly also disallows moving of X4s. Copying is allowed, but deprecated. I strongly recommend that if you declare one of these five function, you explicitly declare all. For example: template<class T> class Handle { T* p; public: Handle(T* pp) : p{pp} {} ~Handle() { delete p; } // user-defined destructor: no implicit copy or move Handle(Handle&& h) :p{h.p} { h.p=nullptr; } // transfer ownership Handle& operator=(Handle&& h) { delete p; p=h.p; h.p=nullptr; return *this; } // transfer ownership Handle(const Handle&) = delete; // no copy Handle& operator=(const Handle&) = delete; // ... }; See also the C++ draft section ???

[N2326==07-0186] Lawrence Crowl: Defaulted and Deleted Functions.

[N3174=100164] B. Stroustrup: To move or not to move. An analysis of problems related to generated copy and move operations. Approved. enum class -- scoped and strongly typed enums The enum classes ("new enums", "strong enums") address three problems with traditional C++ enumerations: conventional enum s implicitly convert to int , causing errors when someone does not want an enumeration to act as an integer.

s implicitly convert to , causing errors when someone does not want an enumeration to act as an integer. conventional enum s export their enumerators to the surrounding scope, causing name clashes.

s export their enumerators to the surrounding scope, causing name clashes. the underlying type of an enum cannot be specified, causing confusion, compatibility problems, and makes forward declaration impossible. enum classs ("strong enums") are strongly typed and scoped: enum Alert { green, yellow, orange, red }; // traditional enum enum class Color { red, blue }; // scoped and strongly typed enum // no export of enumerator names into enclosing scope // no implicit conversion to int enum class TrafficLight { red, yellow, green }; Alert a = 7; // error (as ever in C++) Color c = 7; // error: no int->Color conversion int a2 = red; // ok: Alert->int conversion int a3 = Alert::red; // error in C++98; ok in C++11 int a4 = blue; // error: blue not in scope int a5 = Color::blue; // error: not Color->int conversion Color a6 = Color::blue; // ok As shown, traditional enums work as usual, but you can now optionally qualify with the enum's name. The new enums are "enum class" because they combine aspects of traditional enumerations (names values) with aspects of classes (scoped members and absence of conversions). Being able to specify the underlying type allow simpler interoperability and guaranteed sizes of enumerations: enum class Color : char { red, blue }; // compact representation enum class TrafficLight { red, yellow, green }; // by default, the underlying type is int enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U }; // how big is an E? // (whatever the old rules say; // i.e. "implementation defined") enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U }; // now we can be specific It also enables forward declaration of enums: enum class Color_code : char; // (forward) declaration void foobar(Color_code* p); // use of forward declaration // ... enum class Color_code : char { red, yellow, green, blue }; // definition The underlying type must be one of the signed or unsigned integer types; the default is int. In the standard library, enum classes are used For mapping systems specific error codes: In <system_error>: enum class errc;

For pointer safety indicators: In <memory>: enum class pointer_safety { relaxed, preferred, strict };

For I/O stream errors: In <iosfwd>: enum class io_errc { stream = 1 };

For asynchronous communications error handling: In <future>: enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied }; Several of these have operators, such as == defined. See also the C++ draft section 7.2

[N1513=03-0096] David E. Miller: Improving Enumeration Types (original enum proposal).

[N2347 = J16/07-0207] David E. Miller, Herb Sutter, and Bjarne Stroustrup: Strongly Typed Enums (revision 3).

[N2499=08-0009] Alberto Ganesh Barbati: Forward declaration of enumerations. constexpr -- generalized and guaranteed constant expressions The constexpr mechanism provides more general constant expressions

allows constant expressions involving user-defined types

provides a way to guarantee that an initialization is done at compile time Consider enum Flags { good=0, fail=1, bad=2, eof=4 }; constexpr int operator|(Flags f1, Flags f2) { return Flags(int(f1)|int(f2)); } void f(Flags x) { switch (x) { case bad: /* ... */ break; case eof: /* ... */ break; case bad|eof: /* ... */ break; default: /* ... */ break; } } Here constexpr says that the function must be of a simple form so that it can be evaluated at compile time if given constant expressions arguments. In addition to be able to evaluate expressions at compile time, we want to be able to require expressions to be evaluated at compile time; constexpr in front of a variable definition does that (and implies const): constexpr int x1 = bad|eof; // ok void f(Flags f3) { constexpr int x2 = bad|f3; // error: can't evaluate at compile time int x3 = bad|f3; // ok } Typically we want the compile-time evaluation guarantee for global or namespace objects, often for objects we want to place in read-only storage. This also works for objects for which the constructors are simple enough to be constexpr and expressions involving such objects: struct Point { int x,y; constexpr Point(int xx, int yy) : x(xx), y(yy) { } }; constexpr Point origo(0,0); constexpr int z = origo.x; constexpr Point a[] = {Point(0,0), Point(1,1), Point(2,2) }; constexpr int x = a[1].x; // x becomes 1 Please note that constexpr is not a general purpose replacement for const (or vise versa): const 's primary function is to express the idea that an object is not modified through an interface (even though the object may very well be modified through other interfaces). It just so happens that declaring an object const provides excellent optimization opportunities for the compiler. In particular, if an object is declared const and its address isn't taken, a compiler is often able to evaluate its initializer at compile time (though that's not guaranteed) and keep that object in its tables rather than emitting it into the generated code.

's primary function is to express the idea that an object is not modified through an interface (even though the object may very well be modified through other interfaces). It just so happens that declaring an object provides excellent optimization opportunities for the compiler. In particular, if an object is declared and its address isn't taken, a compiler is often able to evaluate its initializer at compile time (though that's not guaranteed) and keep that object in its tables rather than emitting it into the generated code. constexpr's primary function is to extend the range of what can be computed at compile time, making such computation type safe. Objects declared constexpr have their initializer evaluated at compile time; they are basically values kept in the compiler's tables and only emitted into the generated code if needed. See also the C++ draft 3.6.2 Initialization of non-local objects, 3.9 Types [12], 5.19 Constant expressions, 7.1.5 The constexpr specifier

[N1521=03-0104] Gabriel Dos Reis: Generalized Constant Expressions (original proposal).

[N2235=07-0095] Gabriel Dos Reis, Bjarne Stroustrup, and Jens Maurer: Generalized Constant Expressions -- Revision 5. decltype -- the type of an expression decltype(E) is the type ("declared type") of the name or expression E and can be used in declarations. For example: void f(const vector<int>& a, vector<float>& b) { typedef decltype(a[0]*b[0]) Tmp; for (int i=0; i<b.size(); ++i) { Tmp* p = new Tmp(a[i]*b[i]); // ... } // ... } This notion has been popular in generic programming under the label "typeof" for a long time, but the typeof implementations in actual use were incomplete and incompatible, so the standard version is named decltype. If you just need the type for a variable that you are about to initialize auto is often a simpler choice. You really need decltype if you need a type for something that is not a variable, such as a return type. See also the C++ draft 7.1.6.2 Simple type specifiers

[Str02] Bjarne Stroustrup. Draft proposal for "typeof". C++ reflector message c++std-ext-5364, October 2002. (original suggestion).

[N1478=03-0061] Jaakko Jarvi, Bjarne Stroustrup, Douglas Gregor, and Jeremy Siek: Decltype and auto (original proposal).

[N2343=07-0203] Jaakko Jarvi, Bjarne Stroustrup, and Gabriel Dos Reis: Decltype (revision 7): proposed wording. Initializer lists Consider vector<double> v = { 1, 2, 3.456, 99.99 }; list<pair<string,string>> languages = { {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"} }; map<vector<string>,vector<int>> years = { { {"Maurice","Vincent", "Wilkes"},{1913, 1945, 1951, 1967, 2000} }, { {"Martin", "Ritchards"}, {1982, 2003, 2007} }, { {"David", "John", "Wheeler"}, {1927, 1947, 1951, 2004} } }; Initializer lists are not just for arrays any more. The mechanism for accepting a {}-list is a function (often a constructor) accepting an argument of type std::initializer_list<T>. For example: void f(initializer_list<int>); f({1,2}); f({23,345,4567,56789}); f({}); // the empty list f{1,2}; // error: function call ( ) missing years.insert({{"Bjarne","Stroustrup"},{1950, 1975, 1985}}); The initializer list can be of arbitrary length, but must be homogeneous (all elements must be of a the template argument type, T, or convertible to T). A container might implement an initializer-list constructor like this: template<class E> class vector { public: vector (std::initializer_list<E> s) // initializer-list constructor { reserve(s.size()); // get the right amount of space uninitialized_copy(s.begin(), s.end(), elem); // initialize elements (in elem[0:s.size())) sz = s.size(); // set vector size } // ... as before ... }; The distinction between direct initialization and copy initialization is maintained for {}-initialization, but becomes relevant less frequently because of {}-initialization. For example, std::vector has an explicit constructor from int and an initializer-list constructor: vector<double> v1(7); // ok: v1 has 7 elements v1 = 9; // error: no conversion from int to vector vector<double> v2 = 9; // error: no conversion from int to vector void f(const vector<double>&); f(9); // error: no conversion from int to vector vector<double> v1{7}; // ok: v1 has 1 element (with its value 7.0) v1 = {9}; // ok v1 now has 1 element (with its value 9.0) vector<double> v2 = {9}; // ok: v2 has 1 element (with its value 9.0) f({9}); // ok: f is called with the list { 9 } vector<vector<double>> vs = { vector<double>(10), // ok: explicit construction (10 elements) vector<double>{10}, // ok: explicit construction (1 element with the value 10.0) 10 // error: vector's constructor is explicit }; The function can access the initializer_list as an immutable sequence. For example: void f(initializer_list<int> args) { for (auto p=args.begin(); p!=args.end(); ++p) cout << *p << "

"; } A constructor that takes a single argument of type std::initializer_list is called an initializer-list constructor. The standard library containers, string, and regex have initializer-list constructors, assignment, etc. An initializer-list can be used as a range, e.g. in a range for statement The initializer lists are part of the scheme for uniform and general initialization. See also the C++ draft 8.5.4 List-initialization [dcl.init.list]

[N1890=05-0150 ] Bjarne Stroustrup and Gabriel Dos Reis: Initialization and initializers (an overview of initialization-related problems with suggested solutions).

[N1919=05-0179] Bjarne Stroustrup and Gabriel Dos Reis: Initializer lists.

[N2215=07-0075] Bjarne Stroustrup and Gabriel Dos Reis : Initializer lists (Rev. 3) .

[N2640=08-0150] Jason Merrill and Daveed Vandevoorde: Initializer Lists -- Alternative Mechanism and Rationale (v. 2) (final proposal). Preventing narrowing The problem: C and C++ implicitly truncates: int x = 7.3; // Ouch! void f(int); f(7.3); // Ouch! However, in C++11, {} initialization doesn't narrow: int x0 {7.3}; // error: narrowing int x1 = {7.3}; // error: narrowing double d = 7; int x2{d}; // error: narrowing (double to int) char x3{7}; // ok: even though 7 is an int, this is not narrowing vector<int> vi = { 1, 2.3, 4, 5.6 }; // error: double to int narrowing The way C++11 avoids a lot of incompatibilities is by relying on the actual values of initializers (such as 7 in the example above) when it can (and not just type) when deciding what is a narrowing conversion. If a value can be represented exactly as the target type, the conversion is not narrowing. char c1{7}; // OK: 7 is an int, but it fits in a char char c2{77777}; // error: narrowing (assuming 8-bit chars) Note that floating-point to integer conversions are always considered narrowing -- even 7.0 to 7. See also the C++ draft section 8.5.4.

[N1890=05-0150 ] Bjarne Stroustrup and Gabriel Dos Reis: Initialization and initializers (an overview of initialization-related problems with suggested solutions).

[N2215=07-0075] Bjarne Stroustrup and Gabriel Dos Reis : Initializer lists (Rev. 3) .

[N2640=08-0150] Jason Merrill and Daveed Vandevoorde: Initializer Lists - Alternative Mechanism and Rationale (v. 2) (primarily on "explicit"). Delegating constructors In C++98, if you want two constructors to do the same thing, repeat yourself or call "an init() function." For example: class X { int a; void validate(int x) { if (0<x && x<=max) a=x; else throw bad_X(x); } public: X(int x) { validate(x); } X() { validate(42); } X(string s) { int x = lexical_cast<int>(s); validate(x); } // ... }; Verbosity hinders readability and repetition is error-prone. Both get in the way of maintainability. So, in C++11, we can define one constructor in terms of another: class X { int a; public: X(int x) { if (0<x && x<=max) a=x; else throw bad_X(x); } X() :X{42} { } X(string s) :X{lexical_cast<int>(s)} { } // ... }; See also the C++ draft section 12.6.2

N1986==06-0056 Herb Sutter and Francis Glassborow: Delegating Constructors (revision 3). In-class member initializers In C++98, only static const members of integral types can be initialized in-class, and the initializer has to be a constant expression. These restrictions ensure that we can do the initialization at compile-time. For example: int var = 7; class X { static const int m1 = 7; // ok const int m2 = 7; // error: not static static int m3 = 7; // error: not const static const int m4 = var; // error: initializer not constant expression static const string m5 = "odd"; // error: not integral type // ... }; The basic idea for C++11 is to allow a non-static data member to be initialized where it is declared (in its class). A constructor can then use the initializer when run-time initialization is needed. Consider: class A { public: int a = 7; }; This is equivalent to: class A { public: int a; A() : a(7) {} }; This saves a bit of typing, but the real benefits come in classes with multiple constructors. Often, all constructors use a common initializer for a member: class A { public: A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {} A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {} A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {} int a, b; private: HashingFunction hash_algorithm; // Cryptographic hash to be applied to all A instances std::string s; // String indicating state in object lifecycle }; The fact that hash_algorithm and s each has a single default is lost in the mess of code and could easily become a problem during maintenance. Instead, we can factor out the initialization of the data members: class A { public: A(): a(7), b(5) {} A(int a_val) : a(a_val), b(5) {} A(D d) : a(7), b(g(d)) {} int a, b; private: HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances std::string s{"Constructor run"}; // String indicating state in object lifecycle }; If a member is initialized by both an in-class initializer and a constructor, only the constructor's initialization is done (it "overrides" the default). So we can simplify further: class A { public: A() {} A(int a_val) : a(a_val) {} A(D d) : b(g(d)) {} int a = 7; int b = 5; private: HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances std::string s{"Constructor run"}; // String indicating state in object lifecycle }; See also the C++ draft section "one or two words all over the place"; see proposal.

[N2628=08-0138] Michael Spertus and Bill Seymour: Non-static data member initializers. Inherited constructors People sometimes are confused about the fact that ordinary scope rules apply to class members. In particular, a member of a base class is not in the same scope as a member of a derived class: struct B { void f(double); }; struct D : B { void f(int); }; B b; b.f(4.5); // fine D d; d.f(4.5); // surprise: calls f(int) with argument 4 In C++98, we can "lift" a set of overloaded functions from a base class into a derived class: struct B { void f(double); }; struct D : B { using B::f; // bring all f()s from B into scope void f(int); // add a new f() }; B b; b.f(4.5); // fine D d; d.f(4.5); // fine: calls D::f(double) which is B::f(double) I have said that "Little more than a historical accident prevents using this to work for a constructor as well as for an ordinary member function." C++11 provides that facility: class Derived : public Base { public: using Base::f; // lift Base's f into Derived's scope -- works in C++98 void f(char); // provide a new f void f(int); // prefer this f to Base::f(int) using Base::Base; // lift Base constructors Derived's scope -- C++11 only Derived(char); // provide a new constructor Derived(int); // prefer this constructor to Base::Base(int) // ... }; If you so choose, you can still shoot yourself in the foot by inheriting constructors in a derived class in which you define new member variables needing initialization: struct B1 { B1(int) { } }; struct D1 : B1 { using B1::B1; // implicitly declares D1(int) int x; }; void test() { D1 d(6); // Oops: d.x is not initialized D1 e; // error: D1 has no default constructor } You might remove the bullet from your foot by using a member-initializer:

struct D1 : B1 { using B1::B1; // implicitly declares D1(int) int x{0}; // note: x is initialized }; void test() { D1 d(6); // d.x is zero }

See also

the C++ draft section 12.9.

[N1890=05-0150 ] Bjarne Stroustrup and Gabriel Dos Reis: Initialization and initializers (an overview of initialization-related problems with suggested solutions).

[N1898=05-0158 ] Michel Michaud and Michael Wong: Forwarding and inherited constructors .

[N2512=08-0022] Alisdair Meredith, Michael Wong, Jens Maurer: Inheriting Constructors (revision 4).

Static (compile-time) assertions -- static_assert

static_assert(expression,string);

static_assert(sizeof(long)>=8, "64-bit code generation required for this library."); struct S { X m1; Y m2; }; static_assert(sizeof(S)==sizeof(X)+sizeof(Y),"unexpected padding in S");

int f(int* p, int n) { static_assert(p==0,"p is not null"); // error: static_assert() expression not a constant expression // ... }

See also

long long -- a longer integer

long long x = 9223372036854775807LL;

See also

nullptr -- a null pointer literal

char* p = nullptr; int* q = nullptr; char* p2 = 0; // 0 still works and p==p2 void f(int); void f(char*); f(0); // call f(int) f(nullptr); // call f(char*) void g(int); g(nullptr); // error: nullptr is not an int int i = nullptr; // error nullptr is not an int

See also

Suffix return type syntax

template<class T, class U> ??? mul(T x, U y) { return x*y; }

template<class T, class U> decltype(x*y) mul(T x, U y) // scope problem! { return x*y; }

template<class T, class U> decltype(*(T*)(0)**(U*)(0)) mul(T x, U y) // ugly! and error prone { return x*y; }

The solution is put the return type where it belongs, after the arguments:

template<class T, class U> auto mul(T x, U y) -> decltype(x*y) { return x*y; }

The suffix syntax is not primarily about templates and type deduction, it is really about scope.

struct List { struct Link { /* ... */ }; Link* erase(Link* p); // remove p and return the link before p // ... }; List::Link* List::erase(Link* p) { /* ... */ }

auto List::erase(Link* p) -> Link* { /* ... */ }

See also

the C++ draft section ???

[Str02] Bjarne Stroustrup. Draft proposal for "typeof". C++ reflector message c++std-ext-5364, October 2002.

[N1478=03-0061] Jaakko Jarvi, Bjarne Stroustrup, Douglas Gregor, and Jeremy Siek: Decltype and auto.

[N2445=07-0315] Jason Merrill: New Function Declarator Syntax Wording.

[N2825=09-0015] Lawrence Crowl and Alisdair Meredith: Unified Function Syntax.

template alias (formerly known as "template typedef")

template<class T> using Vec = std::vector<T,My_alloc<T>>; // standard vector using my allocator Vec<int> fib = { 1, 2, 3, 5, 8, 13 }; // allocates elements using My_alloc vector<int,My_alloc<int>> verbose = fib; // verbose and fib are of the same type

Specialization works (you can alias a set of specializations but you cannot specialize an alias) For example: template<int> struct int_exact_traits { // idea: int_exact_trait<N>::type is a type with exactly N bits typedef int type; }; template<> struct int_exact_traits<8> { typedef char type; }; template<> struct int_exact_traits<16> { typedef char[2] type; }; // ... template<int N> using int_exact = typename int_exact_traits<N>::type; // define alias for convenient notation int_exact<8> a = 7; // int_exact<8> is an int with 8 bits In addition to being important in connection with templates, type aliases can also be used as a different (and IMO better) syntax for ordinary type aliases:

typedef void (*PFD)(double); // C style using PF = void (*)(double); // using plus C-style type using P = [](double)->void; // using plus suffix return type

See also

the C++ draft: 14.6.7 Template aliases; 7.1.3 The typedef specifier

[N1489=03-0072] Bjarne Stroustrup and Gabriel Dos Reis: Templates aliases for C++.

[N2258=07-0118] Gabriel Dos Reis and Bjarne Stroustrup: Templates Aliases (Revision 3) (final proposal).

Variadic Templates

How to construct a class with 1, 2, 3, 4, 5, 6, 7, 8, 9, or ... initializers?

How to avoid constructing an object out of parts and then copying the result?

How to construct a tuple?

Here is an example (from ``A brief introduction to Variadic templates'' (see references)) implementing a general, type-safe, printf(). It would probably be better to use boost::format, but consider:

const string pi = "pi"; const char* m = "The value of %s is about %g (unless you live in %s).

"; printf(m,pi,3.14159,"Indiana");

void printf(const char* s) { while (s && *s) { if (*s=='%' && *++s!='%') // make sure that there wasn't meant to be more arguments // %% represents plain % in a format string throw runtime_error("invalid format: missing arguments"); std::cout << *s++; } }

template<typename T, typename... Args> // note the "..." void printf(const char* s, T value, Args... args) // note the "..." { while (s && *s) { if (*s=='%' && *++s!='%') { // a format specifier (ignore which one it is) std::cout << value; // use first non-format argument return printf(++s, args...); // ``peel off'' first argument } std::cout << *s++; } throw std::runtime error("extra arguments provided to printf"); }

The Args...defines what is called a ``parameter pack.'' That's basically a sequence of (type/value) pairs from which you can ``peel off'' arguments starting with the first. When printf() is called with one argument, the first definition (printf(const char*)) is chosen. When printf() is called with two or more arguments, the second definition (printf(const char*, T value, Args... args)) is chosen, with the first argument as s, the second as value, and the rest (if any) bundled into the parameter pack args for later use. In the call

printf(++s, args...);

If you are familiar with functional programming, you should find this an unusual notation for a pretty standard technique. If not, here are some small technical examples that might help. First we can declare and use a simple variadic template function (just like printf() above):

template<class ... Types> void f(Types ... args); // variadic template function // (i.e. a function that can take an arbitrary number of arguments of arbitrary types) f(); // OK: args contains no arguments f(1); // OK: args contains one argument: int f(2, 1.0); // OK: args contains two arguments: int and double

template<typename Head, typename... Tail> class tuple<Head, Tail...> : private tuple<Tail...> { // here is the recursion // Basically, a tuple stores its head (first (type/value) pair // and derives from the tuple of its tail (the rest of the (type/value) pairs. // Note that the type is encoded in the type, not stored as data typedef tuple<Tail...> inherited; public: tuple() { } // default: the empty tuple // Construct tuple from separate arguments: tuple(typename add_const_reference<Head>::type v, typename add_const_reference<Tail>::type... vtail) : m_head(v), inherited(vtail...) { } // Construct tuple from another tuple: template<typename... VValues> tuple(const tuple<VValues...>& other) : m_head(other.head()), inherited(other.tail()) { } template<typename... VValues> tuple& operator=(const tuple<VValues...>& other) // assignment { m_head = other.head(); tail() = other.tail(); return *this; } typename add_reference<Head>::type head() { return m_head; } typename add_reference<const Head>::type head() const { return m_head; } inherited& tail() { return *this; } const inherited& tail() const { return *this; } protected: Head m_head; }

tuple<string,vector<int>,double> tt("hello",{1,2,3,4},1.2); string h = tt.head(); // "hello" tuple<vector<int>,double> t2 = tt.tail(); // {{1,2,3,4},1.2};

template<class... Types> tuple<Types...> make_tuple(Types&&... t) // this definition is somewhat simplified (see standard 20.5.2.2) { return tuple<Types...>(t...); } string s = "Hello"; vector<int> v = {1,22,3,4,5}; auto x = make_tuple(s,v,1.2);

See also:

Uniform initialization syntax and semantics

string a[] = { "foo", " bar" }; // ok: initialize array variable vector<string> v = { "foo", " bar" }; // error: initializer list for non-aggregate vector void f(string a[]); f( { "foo", " bar" } ); // syntax error: block as argument

int a = 2; // ``assignment style'' int aa[] = { 2, 3 }; // assignment style with list complex z(1,2); // ``functional style'' initialization x = Ptr(y); // ``functional style'' for conversion/cast/construction

int a(1); // variable definition int b(); // function declaration int b(foo); // variable definition or function declaration

The C++11 solution is to allow {}-initializer lists for all initialization:

X x1 = X{1,2}; X x2 = {1,2}; // the = is optional X x3{1,2}; X* p = new X{1,2}; struct D : X { D(int x, int y) :X{x,y} { /* ... */ }; }; struct S { int a[3]; S(int x, int y, int z) :a{x,y,z} { /* ... */ }; // solution to old problem };

X x{a}; X* p = new X{a}; z = X{a}; // use as cast f({a}); // function argument (of type X) return {a}; // function return value (function returning X)

See also

Rvalue references

void incr(int& a) { ++a; } int i = 0; incr(i); // i becomes 1 incr(0); // error: 0 is not an lvalue

So far, so good, but consider

template<class T> swap(T& a, T& b) // "old style swap" { T tmp(a); // now we have two copies of a a = b; // now we have two copies of b b = tmp; // now we have two copies of tmp (aka a) }

In C++11, we can define "move constructors" and "move assignments" to move rather than copy their argument:

template<class T> class vector { // ... vector(const vector&); // copy constructor vector(vector&&); // move constructor vector& operator=(const vector&); // copy assignment vector& operator=(vector&&); // move assignment }; // note: move constructor and move assignment takes non-const && // they can, and usually do, write to their argument

X a; X f(); X& r1 = a; // bind r1 to a (an lvalue) X& r2 = f(); // error: f() is an rvalue; can't bind X&& rr1 = f(); // fine: bind rr1 to temporary X&& rr2 = a; // error: bind a is an lvalue

How do we know whether it's ok to simply move from a source? We tell the compiler:

template<class T> void swap(T& a, T& b) // "perfect swap" (almost) { T tmp = move(a); // could invalidate a a = move(b); // could invalidate b b = move(tmp); // could invalidate tmp }

Rvalue references can also be used to provide perfect forwarding.

In the C++11 standard library, all containers are provided with move constructors and move assignment and operations that insert new elements, such as insert() and push_back() have versions that take rvalue references. The net result is that the standard containers and algorithms quietly - without user intervention - improve in performance because they copy less.

See also

unions (generalized)

union U { int m1; complex<double> m2; // error (silly): complex has constructor string m3; // error (not silly): string has a serious invariant // maintained by ctor, copy, and dtor };

U u; // which constructor, if any? u.m1 = 1; // assign to int member string s = u.m3; // disaster: read from string member

C++11 modifies the restrictions of unions to make more member types feasible; in particular, it allows a member of types with constructors and destructors. It also adds a restriction to make the more flexible unions less error-prone by encouraging the building of discriminated unions.

Union member types are restricted:

No virtual functions (as ever)

No references (as ever)

No bases (as ever)

If a union has a member with a user-defined constructor, copy, or destructor then that special function is deleted; that is, it cannot be used for an object of the union type. This is new.

union U1 { int m1; complex<double> m2; // ok }; union U2 { int m1; string m3; // ok };

U1 u; // ok u.m2 = {1,2}; // ok: assign to the complex member U2 u2; // error: the string destructor caused the U2 destructor to be deleted U2 u3 = u2; // error: the string copy constructor caused the U2 copy constructor to be deleted

class Widget { // Three alternative implementations represented as a union private: enum class Tag { point, number, text } type; // discriminant union { // representation point p; // point has constructor int i; string s; // string has default constructor, copy operations, and destructor }; // ... Widget& operator=(const Widget& w) // necessary because of the string variant { if (type==Tag::text && w.type==Tag::text) { s = w.s; // usual string assignment return *this; } if (type==Tag::text) s.~string(); // destroy (explicitly!) switch (w.type) { case Tag::point: p = w.p; break; // normal copy case Tag::number: i = w.i; break; case Tag::text: new(&s)(w.s); break; // placement new } type = w.type; return *this; } };

li>the C++ draft section 9.5 [N2544=08-0054] Alan Talbot, Lois Goldthwaite, Lawrence Crowl, and Jens Maurer: Unrestricted unions (Revision 2)

PODs (generalized)

struct S { int a; }; // S is a POD struct SS { int a; SS(int aa) : a(aa) { } }; // SS is not a POD struct SSS { virtual void f(); /* ... */ };

If all your members and bases are PODs, you're a POD

As usual (details in section 9 [10]) No virtual functions No virtual bases No references No multiple access specifiers



See also:

the C++ draft section 3.9 and 9 [10]

[N2294=07-0154] Beman Dawes: POD's Revisited; Resolving Core Issue 568 (Revision 4).

Raw string literals

string s = "\\w\\\\\\w"; // I hope I got that right

string s = R"(\w\\\w)"; // I'm pretty sure I got that right

"('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|" // Are the five backslashes correct or not? // Even experts become easily confused.

R"("quoted string")" // the string is "quoted string"

R"***("quoted string containing the usual terminator (")")***" // the string is "quoted string containing the usual terminator (")"

The initial R of a raw string can be preceded by an encoding-prefix: u8, u, U, or L. For example u8R"(fdfdfa)" is an UTF-8 string literal.

See

User-defined literals

123 // int 1.2 // double 1.2F // float 'a' // char 1ULL // unsigned long long 0xD0 // hexadecimal unsigned "as" // string

"Hi!"s // string, not ``zero-terminated array of char'' 1.2i // imaginary 123.4567891234df // decimal floating point (IBM) 101010111000101b // binary 123s // seconds 123.56km // not miles! (units) 1234567890123456789012345678901234567890x // extended-precision

constexpr complex<double> operator "" i(long double d) // imaginary literal { return {0,d}; // complex is a literal type } std::string operator""s (const char* p, size_t n) // std::string literal { return string(p,n); // requires free store allocation }

template<class T> void f(const T&); f("Hello"); // pass pointer to const char* f("Hello"s); // pass (5-character) string object f("Hello

"s); // pass (6-character) string object auto z = 2+1i; // complex (2,1)

To get an ``uncooked'' string, simply request a single const char* argument:

Bignum operator"" x(const char* p) { return Bignum(p); } void f(Bignum); f(1234567890123456789012345678901234567890x);

There are four kinds of literals that can be suffixed to make a user-defined literal

integer literal: accepted by a literal operator taking a single unsigned long long or const char* argument.

or argument. floating-point literal: accepted by a literal operator taking a single long double or const char* argument.

or argument. string literal: accepted by a literal operator taking a pair of (const char*, size_t) arguments.

arguments. character literal: accepted by a literal operator taking a single char argument.

string operator"" S(const char* p); // warning: this will not work as expected "one two"S; // error: no applicable literal operator

Suffixes will tend to be short (e.g. s for string, i for imaginary, m for meter, and x for extended), so different uses could easily clash. Use namespaces to prevent clashes:

namespace Numerics { // ... class Bignum { /* ... */ }; namespace literals { operator"" X(char const*); } } using namespace Numerics::literals;

See also:

Standard 2.14.8 User-defined literals

[N2378==07-0238] Ian McIntosh, Michael Wong, Raymond Mak, Robert Klarer, Jens Mauer, Alisdair Meredith, Bjarne Stroustrup, David Vandevoorde: User-defined Literals (aka. Extensible Literals (revision 3)).

Attributes

void f [[ noreturn ]] () // f() will never return { throw "error"; // OK } struct foo* f [[carries_dependency]] (int i); // hint to optimizer int* g(int* x, int* y [[carries_dependency]]);

There is a reasonable fear that attributes will be used to create language dialects. The recommendation is to use attributes to only control things that do not affect the meaning of a program but might help detect errors (e.g. [[noreturn]]) or help optimizers (e.g. [[carries_dependency]]).

One planned use for attributes is improved support for OpenMP. For example:

for [[omp::parallel()]] (int i=0; i<v.size(); ++i) { // ... }

See also:

Standard: 7.6.1 Attribute syntax and semantics, 7.6.3-4 noreturn, carries_dependency 8 Declarators, 9 Classes, 10 Derived classes, 12.3.2 Conversion functions

[N2418=07-027] Jens Maurer, Michael Wong: Towards support for attributes in C++ (Revision 3)

Lambdas

vector<int> v = {50, -10, 20, -30}; std::sort(v.begin(), v.end()); // the default sort // now v should be { -30, -10, 20, 50 } // sort by absolute value: std::sort(v.begin(), v.end(), [](int a, int b) { return abs(a)<abs(b); }); // now v should be { -10, 20, -30, 50 }

A lambda expression can access local variables in the scope in which it is used. For example:

void f(vector<Record>& v) { vector<int> indices(v.size()); int count = 0; generate(indices.begin(),indices.end(),[&count](){ return count++; }); // sort indices in the order determined by the name field of the records: std::sort(indices.begin(), indices.end(), [&](int a, int b) { return v[a].name<v[b].name; }); // ... }

The [&] is a "capture list" specifying that local names used will be passed by reference. We could have said that we wanted to "capture" only v, we could have said so: [&v]. Had we wanted to pass v by value, we could have said so: [=v]. Capture nothing is [], capture all by references is [&], and capture all by value is [=].

If an action is neither common nor simple, I recommend using a named function object or function. For example, the example above could have been written:

void f(vector<Record>& v) { vector<int> indices(v.size()); int count = 0; generate(indices.begin(),indices.end(),[&](){ return ++count; }); struct Cmp_names { const vector<Record>& vr; Cmp_names(const vector<Record>& r) :vr(r) { } bool operator()(int a, int b) const { return vr[a].name<vr[b].name; } }; // sort indices in the order determined by the name field of the records: std::sort(indices.begin(), indices.end(), Cmp_names(v)); // ... }

To specify a lambda you must provide

its capture list: the list of variables it can use (in addition to its arguments), if any ( [&] meaning "all local variables passed by reference" in the Record comparison example). If no names needs to be captured, a lambda starts with plain [] .

meaning "all local variables passed by reference" in the Record comparison example). If no names needs to be captured, a lambda starts with plain . (optionally) its arguments and their types (e.g, (int a, int b) )

) The action to be performed as a block (e.g., { return v[a].name<v[b].name; } ).

). (optionally) the return type using the new suffix return type syntax; but typically we just deduce the return type from the return statement. If no value is returned void is deduced.

Local types as template arguments

void f(vector<X>& v) { struct Less { bool operator()(const X& a, const X& b) { return a.v<b.v; } }; sort(v.begin(), v.end(), Less()); // C++98: error: Less is local // C++11: ok }

void f(vector<X>& v) { sort(v.begin(), v.end(), [] (const X& a, const X& b) { return a.v<b.v; }); // C++11 }

C++11 also allows values of unnamed types to be used as template arguments:

template<typename T> void foo(T const& t){} enum X { x }; enum { y }; int main() { foo(x); // C++98: ok; C++11: ok foo(y); // C++98: error; C++11: ok enum Z { z }; foo(z); // C++98: error; C++11: ok }

noexcept -- preventing exception propagation

extern "C" double sqrt(double) noexcept; // will never throw vector<double> my_computation(const vector<double>& v) noexcept // I'm not prepared to handle memory exhaustion { vector<double> res(v.size()); // might throw for(int i; i<v.size(); ++i) res[i] = sqrt(v[i]); return res; }

It is possibly to make a function conditionally noexcept. For example, an algorithm can be specified to be noexcept if (and only if) the operations it uses on a template argument are noexcept:

template<class T> void do_f(vector<T>& v) noexcept(noexcept(f(v.at(0)))) // can throw if f(v.at(0)) can { for(int i; i<v.size(); ++i) v.at(i) = f(v.at(i)); }

The noexcept() operator is a constant expression and does not evaluate its operand.

The general form of a noexcept declaration is noexcept(expression) and ``plain noexcept'' is simply a shorthand for noexcept(true). All declarations of a function must have compatible noexcept specifications.

A destructor shouldn't throw; a generated destructor is implicitly noexcept (independently of what code is in its body) if all of the members of its class have noexcept destructors.

It is typically a bad idea to have a move operation throw, so declare those noexcept wherever possible. A generated copy or move operation is implicitly noexcept if all of the copy or move operations it uses on members of its class have noexcept destructors.

noexcept is widely and systematically used in the standard library to improve performance and clarify requirements. See also:

alignment

alignas(double) unsigned char c[1024]; // array of characters, suitably aligned for doubles alignas(16) char[100]; // align on 16 byte boundary

constexpr int n = alignof(int); // ints are aligned on n byte boundaries

See also:

Override controls: override

struct B { virtual void f(); virtual void g() const; virtual void h(char); void k(); // not virtual }; struct D : B { void f(); // overrides B::f() void g(); // doesn't override B::g() (wrong type) virtual void h(char); // overrides B::h() void k(); // doesn't override B::k() (B::k() is not virtual) };

Did the programmer mean to override B::g() ? (almost certainly yes).

? (almost certainly yes). Did the programming mean to override B::h(char) ? (probably not because of the redundant explicit virtual ).

? (probably not because of the redundant explicit ). Did the programmer mean to override B::k()? (probably, but that's not possible).

struct D : B { void f() override; // OK: overrides B::f() void g() override; // error: wrong type virtual void h(char); // overrides B::h(); likely warning void k() override; // error: B::k() is not virtual };

override is only a contextual keyword, so you can still use it as an identifier:

int override = 7; // not recommended

Override controls: final

struct B { virtual void f() const final; // do not override virtual void g(); }; struct D : B { void f() const; // error: D::f attempts to override final B::f void g(); // OK };

If it is performance (inlining) you want or you simply never want to override, it is typically better not to define a function to be virtual in the first place. This is not Java.

final is only a contextual keyword, so you can still use it as an identifier:

int final = 7; // not recommended

See also:

Standard: 10 Derived classes [class.derived] [9]

Standard: 10.3 Virtual functions [class.virtual]

C99 features

long long.

Extended integral types (i.e. rules for optional longer int types).

UCN changes [N2170==07-0030] ``lift the prohibitions on control and basic source universal character names within character and string literals.''

concatenation of narrow/wide strings.

Not VLAs (Variable Length Arrays; thank heaven for small mercies).

__func__ a macro that expands to the name of the lexically current function

a macro that expands to the name of the lexically current function __STDC_HOSTED__

_Pragma : _Pragma( X ) expands to #pragma X

: expands to vararg macros (overloading of macros with different number of arguments) #define report(test, ...) ((test)?puts(#test):printf(_ _VA_ARGS_ _))

empty macro arguments

See:

Extended integer types

See

Dynamic Initialization and Destruction with Concurrency

[N2660 = 08-0170] Lawrence Crowl: Dynamic Initialization and Destruction with Concurrency (Final proposal).

thread-local storage (thread_local)

Unicode characters

?

Copying and rethrowing exceptions

exception_ptr current_exception(); Returns: An exception_ptr object that refers to the currently handled exception (15.3) or a copy of the currently handled exception, or a null exception_ptr object if no exception is being handled. The referenced object shall remain valid at least as long as there is an exception_ptr object that refers to it. ...

void rethrow_exception(exception_ptr p);

template<class E> exception_ptr copy_exception(E e); Effects: as if try { throw e; } catch(...) { return current_exception(); } This is particularly useful for transmitting an exception from one thread to another

Extern templates

#include "MyVector.h" extern template class MyVector<int>; // Suppresses implicit instantiation below -- // MyVector<int> will be explicitly instantiated elsewhere void foo(MyVector<int>& v) { // use the vector in here }

#include "MyVector.h" template class MyVector<int>; // Make MyVector available to clients (e.g., of the shared library)

See

Standard 14.7.2 Explicit instantiation

[N1448==03-0031] Mat Marcus and Gabriel Dos Reis: Controlling Implicit Template Instantiation.

Inline namespace

// file V99.h: inline namespace V99 { void f(int); // does something better than the V98 version void f(double); // new feature // ... } // file V98.h: namespace V98 { void f(int); // does something // ... } // file Mine.h: namespace Mine { #include "V99.h" #include "V98.h" }

#include "Mine.h" using namespace Mine; // ... V98::f(1); // old version V99::f(1); // new version f(1); // default version

This is a very ``static'' and implementer-oriented facility in that the inline specifier has to be placed by the designer of the namespaces -- thus making the choice for all users. It is not possible for a user of Mine to say ``I want the default to be V98 rather than V99.''

See

Standard 7.3.1 Namespace definition [7]-[9].

Explicit conversion operators

struct S { S(int); }; // "ordinary constructor" defines implicit conversion S s1(1); // ok S s2 = 1; // ok void f(S); f(1); // ok (but that's often a bad surprise -- what if S was vector?) struct E { explicit E(int); }; // explicit constructor E e1(1); // ok E e2 = 1; // error (but that's often a surprise) void f(E); f(1); // error (protects against surprises -- e.g. std::vector's constructor from int is explicit)

struct S { S(int) { } /* ... */ }; struct SS { int m; SS(int x) :m(x) { } operator S() { return S(m); } // because S don't have S(SS); non-intrusive }; SS ss(1); S s1 = ss; // ok; like an implicit constructor S s2(ss); // ok ; like an implicit constructor void f(S); f(ss); // ok; like an implicit constructor

struct S { S(int) { } }; struct SS { int m; SS(int x) :m(x) { } explicit operator S() { return S(m); } // because S don't have S(SS) }; SS ss(1); S s1 = ss; // error; like an explicit constructor S s2(ss); // ok ; like an explicit constructor void f(S); f(ss); // error; like an explicit constructor

Standard: 12.3 Conversions

[N2333=07-0193] Lois Goldthwaite, Michael Wong, and Jens Maurer: Explicit Conversion Operator (Revision 1).

Algorithms improvements

New algorithms: bool all_of(Iter first, Iter last, Pred pred); bool any_of(Iter first, Iter last, Pred pred); bool none_of(Iter first, Iter last, Pred pred); Iter find_if_not(Iter first, Iter last, Pred pred); OutIter copy_if(InIter first, InIter last, OutIter result, Pred pred); OutIter copy_n(InIter first, InIter::difference_type n, OutIter result); OutIter move(InIter first, InIter last, OutIter result); OutIter move_backward(InIter first, InIter last, OutIter result); pair<OutIter1, OutIter2> partition_copy(InIter first, InIter last, OutIter1 out_true, OutIter2 out_false, Pred pred); Iter partition_point(Iter first, Iter last, Pred pred); RAIter partial_sort_copy(InIter first, InIter last, RAIter result_first, RAIter result_last); RAIter partial_sort_copy(InIter first, InIter last, RAIter result_first, RAIter result_last, Compare comp); bool is_sorted(Iter first, Iter last); bool is_sorted(Iter first, Iter last, Compare comp); Iter is_sorted_until(Iter first, Iter last); Iter is_sorted_until(Iter first, Iter last, Compare comp); bool is_heap(Iter first, Iter last); bool is_heap(Iter first, Iter last, Compare comp); Iter is_heap_until(Iter first, Iter last); Iter is_heap_until(Iter first, Iter last, Compare comp); T min(initializer_list<T> t); T min(initializer_list<T> t, Compare comp); T max(initializer_list<T> t); T max(initializer_list<T> t, Compare comp); pair<const T&, const T&> minmax(const T& a, const T& b); pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp); pair<const T&, const T&> minmax(initializer_list<T> t); pair<const T&, const T&> minmax(initializer_list<T> t, Compare comp); pair<Iter, Iter> minmax_element(Iter first, Iter last); pair<Iter, Iter> minmax_element(Iter first, Iter last, Compare comp); void iota(Iter first, Iter last, T value); // For each element referred to by the iterator i in the range [first,last), assigns *i = value and increments value as if by ++value

Effects of move : Moving can be much more efficient than copying (see Move semantics). For example, move-based std::sort() and std::set::insert() has been measured to be 15 times faster than copy based versions. This is less impressive than it sounds because such standard library operations for standard library types, such as string and vector , are usually hand-optimized to gain the effects of moving through techniques such as replacing copies with optimized swaps. However, if your type has a move operation, you gain the performance benefits automatically from the standard algorithms. Consider also that the use of moves allows simple and efficient sort (and other algorithms) of containers of ``smart'' pointers, especially unique_ptr: template<class P> struct Cmp<P> { // compare *P values bool operator() (P& a, P& b) const { return *a<*b; } } vector<std::unique_ptr<Big>> vb; // fill vb with unique_ptr's to Big objects sort(vb.begin(),vb.end(),Cmp<unique_ptr<Big>()); // don't try that with an auto_ptr

: Moving can be much more efficient than copying (see Move semantics). For example, move-based std::sort() and std::set::insert() has been measured to be 15 times faster than copy based versions. This is less impressive than it sounds because such standard library operations for standard library types, such as and , are usually hand-optimized to gain the effects of moving through techniques such as replacing copies with optimized swaps. However, if type has a move operation, you gain the performance benefits automatically from the standard algorithms. Use of lambdas : For ages, people have complained about having to write functions or (better) function objects for use as operations, such as Cmp<T> above, for standard library (and other) algorithms. This was especially painful to do if you wrote large functions (don't) because in C++98 you could not define a local function object to use as an argument; now you can. However, lambdas allows us to define operations ``inline:'' sort(vb.begin(),vb.end(),[](unique_ptr<Big> a, unique_ptr<Big> b) { return *a<*b; }); I expect lambdas to be a bit overused initially (like all powerful mechanisms).

: For ages, people have complained about having to write functions or (better) function objects for use as operations, such as above, for standard library (and other) algorithms. This was especially painful to do if you wrote large functions (don't) because in C++98 you could not define a local function object to use as an argument; now you can. However, lambdas allows us to define operations ``inline:'' I expect lambdas to be a bit overused initially (like all powerful mechanisms). Use of initializer lists: Sometimes, initializer lists come in handy as arguments. For example, assuming string variables and Nocase being a case-insensitive comparison: auto x = max({x,y,z},Nocase());

25 Algorithms library [algorithms]

26.7 Generalized numeric operations [numeric.ops]

Howard E. Hinnant, Peter Dimov, and Dave Abrahams: A Proposal to Add Move Semantics Support to the C++ Language. N1377=02-0035.

Container improvements

Initializer lists : The most visible improvement is the use of initializer-list constructors to allow a container to take an initializer list as its argument: vector<string> vs = { "Hello", ", ", "World!", "

" }; for (auto s : vs ) cout << s;

: The most visible improvement is the use of initializer-list constructors to allow a container to take an initializer list as its argument: Move operators : Containers now have move constructors and move assignments (in addition to the traditional copy operations). The most important implication of this is that we can efficiently return a container from a function: vector<int> make_random(int n) { vector<int> ref(n); for(auto& x : ref) x = rand_int(0,255); // some random number generator return ref; } vector<int> v = make_random(10000); for (auto x : make_random(1000000)) cout << x << '

'; The point here is that no vectors are copied. Rewrite this to return a free-store-allocated vector and you have to deal with memory management. Rewrite this to pass the vector to be filled as an argument to make_random() and you have a far less obvious code (plus an added opportunity for making an error).

: Containers now have move constructors and move assignments (in addition to the traditional copy operations). The most important implication of this is that we can efficiently return a container from a function: The point here is that no vectors are copied. Rewrite this to return a free-store-allocated vector and you have to deal with memory management. Rewrite this to pass the vector to be filled as an argument to and you have a far less obvious code (plus an added opportunity for making an error). Improved push operations : My favorite container operation is push_back() that allows a container to grow gracefully: vector<pair<string,int>> vp; string s; int i; while(cin>>s>>i) vp.push_back({s,i}); This will construct a pair<string,int> out of s and i and move it into vp . Note ``move'' not ``copy;'' There is a push_back version that takes an rvalue reference argument so that we can take advantage of string 's move constructor. Note also the use of the unified initializer syntax to avoid verbosity.

: My favorite container operation is that allows a container to grow gracefully: This will construct a out of and and move it into . Note ``move'' not ``copy;'' There is a version that takes an rvalue reference argument so that we can take advantage of 's move constructor. Note also the use of the unified initializer syntax to avoid verbosity. Emplace operations : The push_back() using a move constructor is far more efficient in important cases than the traditional copy-based one, but in extreme cases we can go further. Why copy/move anything? Why not make space in the vector and then construct the desired value in that space? Operations that do that are called ``emplace'' (meaning ``putting in place''). For example emplace_back() : vector<pair<string,int>> vp; string s; int i; while(cin>>s>>i) vp.emplace_back(s,i); An emplace takes a variadic template argument and uses that to construct an object of the desired type. Whether the emplace_back() really is more efficient than the push_back() depends on the types involved and the implementation (of the library and of variadic templates). If you think it matters, measure. Otherwise, choose based on aesthetics: vp.push_back({s,i}); or vp.emplace_back(s,i); . For now, I prefer the push_back() version, but that might change over time.

: The using a move constructor is far more efficient in important cases than the traditional copy-based one, but in extreme cases we can go further. Why copy/move anything? Why not make space in the vector and then construct the desired value in that space? Operations that do that are called ``emplace'' (meaning ``putting in place''). For example : An emplace takes a variadic template argument and uses that to construct an object of the desired type. Whether the really is more efficient than the depends on the types involved and the implementation (of the library and of variadic templates). If you think it matters, measure. Otherwise, choose based on aesthetics: or . For now, I prefer the version, but that might change over time. Scoped allocators: Containers can now hold "real allocation objects (with state)" and use those to control nested/scoped allocation (e.g. allocation of elements in a container)

Compile-time evaluation : constexpr is used to ensure compiler time evaluation in , bitset , duration , char_traits , array, atomic types, random numbers, complex<double> ., etc. In some cases, it means improved performance; in others (where there is no alternative to compile-time evaluation), it means absence of messy low-level code and macros.

: constexpr is used to ensure compiler time evaluation in , , , , array, atomic types, random numbers, ., etc. In some cases, it means improved performance; in others (where there is no alternative to compile-time evaluation), it means absence of messy low-level code and macros. Tuples: Tuples would not be possible without variadic templates.

Scoped allocators

template<class T> class Simple_alloc { // C++98 style // no data // usual allocator stuff }; class Arena { void* p; int s; public: Arena(void* pp, int ss); // allocate from p[0..ss-1] }; template<class T> struct My_alloc { Arena& a; My_alloc(Arena& aa) : a(aa) { } // usual allocator stuff }; Arena my_arena1(new char[100000],100000); Arena my_arena2(new char[1000000],1000000); vector<int> v0; // allocate using default allocator vector<int,My_alloc<int>> v1(My_alloc<int>{my_arena1}); // allocate from my_arena1 vector<int,My_alloc<int>> v2(My_alloc<int>{my_arena2}); // allocate from my_arena2 vector<int,Simple_alloc<int>> v3; // allocate using Simple_alloc

It is not guaranteed that the default allocator and Simple_alloc takes up no space in a vector object, but a bit of elegant template metaprogramming in the library implementation can ensure that. So, using an allocator type imposes a space overhead only if its objects actually has state (like My_alloc).

A rather sneaky problem can occur when using containers and user-defined allocators: Should an element be in the same allocation area as its container? For example, if you use Your_allocator for Your_string to allocate its elements and I use My_allocator to allocate elements of My_vector then which allocator should be used for string elements in My_vector<Your_allocator>? The solution is the ability to tell a container which allocator to pass to elements. For example, assuming that I have an allocator My_alloc and I want a vector<string> that uses My_alloc for both the vector element and string element allocations. First, I must make a version of string that accepts My_alloc objects:

using xstring = basic_string<char, char_traits<char>, My_alloc<char>>; // a string with my allocator

using svec = vector<xstring,scoped_allocator_adaptor<My_alloc<xstring>>>;

svec v(svec::allocator_type(My_alloc<xstring>{my_arena1}));

So, we have four alternatives:

// vector and string use their own (the default) allocator: using svec0 = vector<string>; svec0 v0; // vector (only) uses My_alloc and string uses its own (the default) allocator: using svec1 = vector<string,My_alloc<string>>; svec1 v1(My_alloc<string>{my_arena1}); // vector and string use My_alloc (as above): using xstring = basic_string<char, char_traits<char>, My_alloc<char>>; using svec2 = vector<xstring,scoped_allocator_adaptor<My_alloc<xstring>>>; svec2 v2(scoped_allocator_adaptor<My_alloc<xstring>>{my_arena1}); // vector uses My_alloc and string uses My_string_alloc: using xstring2 = basic_string<char, char_traits<char>, My_string_alloc<char>>; using svec3 = vector<xstring2,scoped_allocator_adaptor<My_alloc<xstring>, My_string_alloc<char>>>; svec3 v3(scoped_allocator_adaptor<My_alloc<xstring2>, My_string_alloc<char>>{my_arena1,my_string_arena});

See also:

Standard: 20.8.5 Scoped allocator adaptor [allocator.adaptor]

Pablo Halpern: The Scoped Allocator Model (Rev 2). N2554=08-0064.

std::array

array<int,6> a = { 1, 2, 3 }; a[3]=4; int x = a[5]; // x becomes 0 because default elements are zero initialized int* p1 = a; // error: std::array doesn't implicitly convert to a pointer int* p2 = a.data(); // ok: get pointer to first element

array<int> a3 = { 1, 2, 3 }; // error: size unknown/missing array<int,0> a0; // ok: no elements int* p = a0.data(); // unspecified; don't try it

template<class C> C::value_type sum(const C& a) { return accumulate(a.begin(),a.end(),0); } array<int,10> a10; array<double,1000> a1000; vector<int> v; // ... int x1 = sum(a10); double x2 = sum(a1000); int x3 = sum(v);

struct Apple : Fruit { /* ... */ }; struct Pear : Fruit { /* ... */ }; void nasty(array<Fruit*,10>& f) { f[7] = new Pear(); }; array<Apple*,10> apples; // ... nasty(apples); // error: can't convert array<Apple*,10> to array<Fruit*,10>;

See also:

Standard: 23.3.1 Class template array

std::forward_list

template <ValueType T, Allocator Alloc = allocator<T> > requires NothrowDestructible<T> class forward_list { public: // the usual container stuff // no size() // no reverse iteration // no back() or push_back() };

See also:

Standard: 23.3.3 Class template forward_list

Unordered containers

unordered_map

unordered_set

unordered_multimap

unordered_multiset

The basic idea is simply to use unordered_map as an optimized version of map where optimization is possible and reasonable. For example:

map<string,int> m { {"Dijkstra",1972}, {"Scott",1976}, {"Wilkes",1967}, {"Hamming",1968} }; m["Ritchie"] = 1983; for(auto x : m) cout << '{' << x.first << ',' << x.second << '}'; unordered_map<string,int> um { {"Dijkstra",1972}, {"Scott",1976}, {"Wilkes",1967}, {"Hamming",1968} }; um["Ritchie"] = 1983; for(auto x : um) cout << '{' << x.first << ',' << x.second << '}';

More to come.

See also:

Standard: 23.5 Unordered associative containers.

std::tuple

The element types of a tuple can explicitly specified or be deduced (using make_tuple()) and the elements can be access by (zero-based) index using get():

tuple<string,int> t2("Kylling",123); auto t = make_tuple(string("Herring"),10, 1.23); // t will be of type tuple<string,int,double> string s = get<0>(t); int x = get<1>(t); double d = get<2>(t);

The most frequently useful tuple is the 2-tuple; that is, a pair. However, pair is directly supported in the standard library through std::pair (20.3.3 Pairs). A pair can be used to initialize a tuple, but the opposite isn't the case.

The comparison operators (==, !=, , and >=) are defined for tuples of comparable element types.

See also:

Standard: 20.5.2 Class template tuple

Variadic template paper

Boost::tuple

metaprogramming and type traits

std::function and std::bind

int f(int,char,double); auto ff = bind(f,_1,'c',1.2); // deduce return type int x = ff(7); // f(7,'c',1.2);

int f(int,char,double); auto frev = bind(f,_3,_2,_1); // reverse argument order int x = frev(1.2,'c',7); // f(7,'c',1.2);

It is not possible to just bind arguments for an overloaded function, we have to explicitly state which version of an overloaded function we want to bind:

int g(int); double g(double); // g() is overloaded auto g1 = bind(g,_1); // error: which g()? auto g2 = bind((double(*)(double))g,_1); // ok (but ugly)

auto f2 = bind<int>(f,7,'c',_1); // explicit return type int x = f2(1.2); // f(7,'c',1.2);

function is a type that can hold a value of just about anything you can invoke using the (...) syntax. In particular, the result of bind can be assigned to a function. function is very simple to use. For example:

function<float (int x, int y)> f; // make a function object struct int_div { // take something you can call using () float operator()(int x, int y) const { return ((float)x)/y; }; }; f = int_div(); // assign cout << f(5, 3) << endl; // call through the function object std::accumulate(b,e,1,f); // passes beautifully

struct X { int foo(int); }; function<int (X*, int)> f; f = &X::foo; // pointer to member X x; int v = f(&x, 5); // call X::foo() for x with 5 function<int (int)> ff = std::bind(f,&x,_1); // first argument for f is &x v=ff(5); // call x.foo(5)

See also:

Standard: 20.7.12 Function template bind, 20.7.16.2 Class template function

Herb Sutter: Generalized Function Pointers. August 2003.

Douglas Gregor: Boost.Function.

Boost::bind

unique_ptr

The unique_ptr (defined in <memory> ) provides a semantics of strict ownership. owns the object it holds a pointer to is not CopyConstructible, nor CopyAssignable; however, it is MoveConstructible and MoveAssignable. stores a pointer to an object and deletes that object using the associated deleter when it is itself destroyed (such as when leaving block scope (6.7)).

(defined in ) provides a semantics of strict ownership. The uses of unique_ptr include providing exception safety for dynamically allocated memory, Passing ownership of dynamically allocated memory to a function returning dynamically allocated memory from a function storing pointers in containers

include "what auto_ptr should have been" (but that we couldn't write in C++98)

Here is a conventional piece of exception unsafe code:

X* f() { X* p = new X; // do something - maybe throw an exception return p; }

X* f() { unique_ptr<X> p(new X); // or {new X} but not = new X // do something - maybe throw an exception return p.release(); }

unique_ptr<X> f() { unique_ptr<X> p(new X); // or {new X} but not = new X // do something - maybe throw an exception return p; // the ownership is transferred out of f() }

void g() { unique_ptr<X> q = f(); // move using move constructor q->memfct(2); // use q X x = *q; // copy the object pointed to // ... } // q and the object it owns is destroyed on exit

One of the uses of unique_ptr is as a pointer in a container, where we might have used a built-in pointer except for exception safety problems (and to guarantee destruction of the pointed to elements):

vector<unique_ptr<string>> vs { new string{"Doug"}, new string{"Adams"} };

unique_ptr is represented by a simple built-in pointer and the overhead of using one compared to a built-in pointer are miniscule. In particular, unique_ptr does not offer any form of dynamic checking.

See also

the C++ draft section 20.7.10

Howard E. Hinnant: unique_ptr Emulation for C++03 Compilers.

shared_ptr

void test() { shared_ptr<int> p1(new int); // count is 1 { shared_ptr<int> p2(p1); // count is 2 { shared_ptr<int> p3(p1); // count is 3 } // count goes back down to 2 } // count goes back down to 1 } // here the count goes to 0 and the int is deleted.

struct Node { // note: a Node may be pointed to from several other nodes. shared_ptr<Node> left; shared_ptr<Node> right; File_handle f; // ... };

Note that you should not use a shared_ptr just to pass a pointer from one owner to another; that's what unique_ptr is for and unique_ptr does that cheaper and better. If you have been using counted pointers as return values from factory functions and the like, consider upgrading to unique_ptr rather than shared_ptr.

Please don't thoughtlessly replace pointers with shared_ptrs in an attempt to prevent memory leaks; shared_ptrs are not a panacea nor are they without costs:

a circular linked structure of shared_ptr s will cause a memory leak (you'll need some logical complication to break the circle, e.g. using a weak_ptr ),

s will cause a memory leak (you'll need some logical complication to break the circle, e.g. using a ), "shared ownership objects" tend to stay "live" for longer than scoped objects (thus causing higher average resource usage),

shared pointers in a multi-threaded environment can be expensive (because of the need to avoid data races on the use count),

a destructor for a shared object does not execute at a predictable time, and

the algorithms/logic for the update of any shared object is easier to get wrong than for an object that's not shared.

See also

the C++ draft: Shared_ptr (20.7.13.3)

weak_ptr

you need access to (only) if it exists, and may get deleted (by someone else), and must have its destructor called after its last use (usually to delete anon-memory resource)

void owner() { // ... vector<shared_ptr<Asteroid>> va(100); for (int i=0; i<va.size(); ++i) { // ... calculate neighbors for new asteroid ... va[i].reset(new Asteroid(weak_ptr<Asteroid>(va[neighbor])); launch(i); } // ... }

Obviously, I radically simplified "the owner" and gave each new Asteroid just one neighbor. The key is that we give the Asteroid a weak_ptr to that neighbor. The owner keeps a shared_ptr to represent the ownership that's shared whenever an Asteroid is looking (but not otherwise). The collision calculation for an Asteroid will look something like this:

void collision(weak_ptr<Asteroid> p) { if (auto q = p.lock()) { // p.lock returns a shared_ptr to p's object // ... that Asteroid still existed: calculate ... } else { // ... oops: that Asteroid has already been destroyed: just forget about it (delete the weak_ptr to it ... } }

I expect to find weak_ptr use much rarer than "plain" shared_ptr use and I hope that unique_ptr will become much more popular than shared_ptr use because unique_ptr represents a simpler (and more efficient) notion of ownership and (therefore) allows better local reasoning.

See also

the C++ draft: Weak_ptr (20.7.13.3)

Garbage collection ABI

The rules for pointers and lifetimes are expressed in terms of "safely derived pointer" (3.7.4.3); roughly: "pointer to something allocated by new or to a sub-object thereof." Here are some examples of "not safely derived pointers" aka "disguised pointers" aka what not to do in a program you want to be considered well behaved and comprehensible to ordinary mortals:

Make a pointer point "elsewhere" for a while int* p = new int; p+=10; // ... collector may run here ... p-=10; *p = 10; // can we be sure that the int is still there?

Hide the pointer in an int int* p = new int; int x = reinterpret_cast<int>(p); // non-portable p=0; // ... collector may run here ... p = reinterpret_cast<int*>(x); *p = 10; // can we be sure that the int is still there?

There are many more and even nastier tricks Think I/O, think "scattering the bits around in different words", ...

A programmer can specify where there are no pointers to be found (e.g. in an image) and what memory can't be reclaimed even if the collector can't find a pointer into it:

void declare_reachable(void* p); // the region of memory starting at p // (and allocated by some allocator // operation which remembers its size) // must not be collected template<class T> T* undeclare_reachable(T* p); void declare_no_pointers(char* p, size_t n); // p[0..n] holds no pointers void undeclare_no_pointers(char* p, size_t n);

enum class pointer_safety {relaxed, preferred, strict }; pointer_safety get_pointer_safety();

relaxed : safely-derived and not safely-derived pointers are treated equivalently; like C and C++98, but that was not my intent - I wanted to allow GC if a user didn't keep a valid pointer around for an object.

: safely-derived and not safely-derived pointers are treated equivalently; like C and C++98, but that was not my intent - I wanted to allow GC if a user didn't keep a valid pointer around for an object. preferred : like relaxed; but a garbage collector may be running as a leak detector and/or detector of dereferences of "bad pointers"

: like relaxed; but a garbage collector may be running as a leak detector and/or detector of dereferences of "bad pointers" strict: safely-derived and not safely-derived pointers may be treated differently, i.e. a garbage collector may be running and will ignore pointers that's not safely derived

See also

Memory model

The key guarantee is: Two threads of execution can update and access separate memory locations without interfering with each other. But what is a ``memory location?'' A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having non-zero width. For example, here S has exactly four separate memory locations:

struct S { char a; // location #1 int b:5, // location #2 int c:11, int :0, // note: :0 is "special" int d:8; // location #3 struct {int ee:8;} e; // location #4 };

// thread 1: char c; c = 1; int x = c; // thread 2: char b; b = 1; int y = b;

So, C++11 guarantees that no such problems occur for ``separate memory locations.'' More precisely: A memory location cannot be safely accessed by two threads without some form of locking unless they are both read accesses. Note that different bitfields within a single word are not separate memory locations, so don't share structs with bitfields among threads without some form of locking. Apart from that caveat, the C++ memory model is simply ``as everyone would expect.''

However, it is not always easy to think straight about low-level concurrency issues. Consider:

// start with x==0 and y==0 if (x) y = 1; // Thread 1 if (y) x = 1; // Thread 2

Is there a problem here? More precisely, is there a data race? (No there isn't).

Fortunately, we have already adapted to modern times and every current C++ compiler (that I know of) gives the one right answer and have done so for years. They do so for most (but unfortunately not yet for all) tricky questions. After all, C++ has been used for serious systems programming of concurrent systems ``forever.'' The standard should further improve things.

See also

Threads

Many thick books and tens of thousands of papers have been writing about concurrency, parallelism, and threading, this FAQ entry barely scratch the surface. It is hard to think clearly about concurrency. If you want to do concurrent programming, at least read a book. Do not rely just on a manual, a standard, or an FAQ.

A thread is launched by constructing a std::thread with a function or a function object (incl. a lambda):

#include<thread> void f(); struct F { void operator()(); }; int main() { std::thread t1{f}; // f() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread }

int main() { std::thread t1{f}; // f() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread t1.join(); // wait for t1 t2.join(); // wait for t2 }

Typically, we'd like to pass some arguments to the task to be executed (I call something executed by a thread a task). For example:

void f(vector<double>&); struct F { vector<double>& v; F(vector<double>& vv) :v{vv} { } void operator()(); }; int main() { std::thread t1{std::bind(f,some_vec)}; // f(some_vec) executes in separate thread std::thread t2{F(some_vec)}; // F(some_vec)() executes in separate thread t1.join(); t2.join(); }

In general, we'd also like to get a result back from an executed task. With plain tasks, there is no notion of a return value; I recommend std::future for that. Alternative, we can pass an argument to a task telling it where to put its result: For example:

void f(vector<double>&, double* res); // place result in res struct F { vector<double>& v; double* res; F(vector<double>& vv, double* p) :v{vv}, res{p} { } void operator()(); // place result in res }; int main() { double res1; double res2; std::thread t1{std::bind(f,some_vec,&res1)}; // f(some_vec,&res1) executes in separate thread std::thread t2{F(some_vec,&res2)}; // F(some_vec,&res2)() executes in separate thread t1.join(); t2.join(); std::cout << res1 << ' ' << res2 << '

'; }

When a thread goes out of scope the program is terminate()d unless its task has completed. That's obviously to be avoided.

There is no way to request a thread to terminate (i.e. request that it exit as a soon as possible and as gracefully as possible) or to force a thread to terminate (i.e. kill it). We are left with the options of

designing our own cooperative ``interruption mechanism'' (with a piece of shared data that a caller thread can set for a called thread to check (and quickly and gracefully exit when it is set)),

``going native'' (using thread::native_handle() to gain access to the operating system's notion of a thread),

to gain access to the operating system's notion of a thread), kill the process ( std::quick_exit() ),

), kill the program (std::terminate()).

The basic problem with threads is data races; that is, two threads running in a single address space can independently access an object in ways that cause undefined results. If one (or both) writes to the object and the other (or both) reads the object they have a ``race'' for who gets its operation(s) done first. The results are not just undefined; they are usually completely unpredictable. Consequently, C++11 provides some rules/guarantees for the programmer to avoid data races:

A C++ standard library function shall not directly or indirectly access objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's arguments, including this .

. A C++ standard library function shall not directly or indirectly modify objects accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function's nonconst arguments, including this .

. C++ standard library implementations are required to avoid data races when different elements in the same sequence are modified concurrently.

You can

See also

Mutual exclusion

std::mutex m; int sh; // shared data // ... m.lock(); // manipulate shared data: sh+=1; m.unlock();

In addition to lock(), a mutex has a try_lock() operation which can be used to try to get into the critical region without the risk of getting blocked:

std::mutex m; int sh; // shared data // ... if (m.try_lock()) { // manipulate shared data: sh+=1; m.unlock(); else { // maybe do something else }

A recursive_mutex is a mutex that can be acquired more than once by a thread:

std::recursive_mutex m; int sh; // shared data // ... void f(int i) { // ... m.lock(); // manipulate shared data: sh+=1; if (--i>0) f(i); m.unlock(); // ... }

What if I need to acquire a mutex within the next ten seconds? The timed_mutex class is offered for that. Its operations are specialized versions of try_lock() with an associated time limit:

std::timed_mutex m; int sh; // shared data // ... if (m.try_lock_for(std::chrono::seconds(10))) { // manipulate shared data: sh+=1; m.unlock(); } else { // we didn't get the mutex; do something else }

std::timed_mutex m; int sh; // shared data // ... if (m.try_lock_until(midnight)) { // manipulate shared data: sh+=1; m.unlock(); } else { // we didn't get the mutex; do something else }

There is of course also a recursive_timed_mutex.

A mutex is considered a resource (as it is typically used to represent a real resource) and must be visible to at least two threads to be useful. Consequently, it cannot be copied or moved (you couldn't just make another copy of a hardware input register).

It can be surprisingly difficult to get the lock()s and unlock()s to match. Think of complicated control structures, errors, and exceptions. If you have a choice, use locks to manage your mutexes; that will save you and your users a lot of sleep.

See also

Locks

std::mutex m; int sh; // shared data // ... void f() { // ... std::unique_lock lck(m); // manipulate shared data: sh+=1; }

This straightforward picture of a lock is clouded by unique_lock having facilities to do just about everything a mutex can, but safer. For example, we can use a lock to do try lock:

std::mutex m; int sh; // shared data // ... void f() { // ... std::unique_lock lck(m,std::defer_lock); // make a lock, but don't acquire the mutex // ... if (lck.try_lock()) { // manipulate shared data: sh+=1; } else { // maybe do something else } }

What if we need two resources represented by two mutexes? The naive way is to acquire the mutexes in order:

std::mutex m1; std::mutex m2; int sh1; // shared data int sh2 // ... void f() { // ... std::unique_lock lck1(m1); std::unique_lock lck2(m2); // manipulate shared data: sh1+=sh2; }

void f() { // ... std::unique_lock lck1(m1,std::defer_lock); // make locks but don't yet try to acquire the mutexes std::unique_lock lck2(m2,std::defer_lock); std::unique_lock lck3(m3,std::defer_lock); lock(lck1,lck2,lck3); // manipulate shared data }

If you prefer to use try_lock()s yourself, there is an equivalent to lock() to help:

void f() { // ... std::unique_lock lck1(m1,std::defer_lock); // make locks but don't yet try to acquire the mutexes std::unique_lock lck2(m2,std::defer_lock); std::unique_lock lck3(m3,std::defer_lock); int x; if ((x = try_lock(lck1,lck2,lck3))==-1) { // welcome to C land // manipulate shared data } else { // x holds the index of a mutex we could not acquire // e.g. if lck2.try_lock() failed x==1 } }

See also

Standard: 30.4.3 Locks [thread.lock]

???

Condition variables

Sorry, I have not had time to write this entry. Please come back later.

See also

Standard: 30.5 Condition variables [thread.condition]

???

Time utilities

If you want to know the current time_point you can call now() for one of three clocks: system_clock, monotonic_clock, high_resolution_clock. For example:

monotonic_clock::time_point t = monotonic_clock::now(); // do something monotonic_clock::duration d = monotonic_clock::now() - t; // something took d time units

auto t = monotonic_clock::now(); // do something auto d = monotonic_clock::now() - t; // something took d time units

The time facilities here are intended to efficiently support uses deep in the system; they do not provide convenience facilities to help you maintain your social calendar. In fact, the time facilities originated with the stringent needs for high-energy physics. To be able to express all time scales (such as centuries and picoseconds), avoid confusion about units, typos, and rounding errors, durations and time_points are expressed using a compile-time rational number package. A duration has two parts: a numbers clock ``tick'' and something (a ``period'') that says what a tick means (is it a second or a millisecond?); the period is part of a durations type. This table from the standard header <ratio>, defining the periods of the SI system (also known as MKS or metric system) might give you an idea of the scope of use:

// convenience SI typedefs: typedef ratio<1, 1000000000000000000000000> yocto; // conditionally supported typedef ratio<1, 1000000000000000000000> zepto; // conditionally supported typedef ratio<1, 1000000000000000000> atto; typedef ratio<1, 1000000000000000> femto; typedef ratio<1, 1000000000000> pico; typedef ratio<1, 1000000000> nano; typedef ratio<1, 1000000> micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio< 10, 1> deca; typedef ratio< 100, 1> hecto; typedef ratio< 1000, 1> kilo; typedef ratio< 1000000, 1> mega; typedef ratio< 1000000000, 1> giga; typedef ratio< 1000000000000, 1> tera; typedef ratio< 1000000000000000, 1> peta; typedef ratio< 1000000000000000000, 1> exa; typedef ratio< 1000000000000000000000, 1> zetta; // conditionally supported typedef ratio<1000000000000000000000000, 1> yotta; // conditionally supported

Here are some examples of values using standard duration types as defined in <chrono>:

microseconds mms = 12345; milliseconds ms = 123; seconds s = 10; minutes m = 30; hours h = 34; auto x = std::chrono::hours(3); // being explicit about namespaces auto x = hours(2)+minutes(35)+seconds(9); // assuming suitable "using"

duration<long> d0 = 5; // seconds (by default) duration<long,kilo> d1 = 99; // kiloseconds! duration<long,ratio<1000,1>> d2 = 100; // d1 and d2 have the same type ("kilo" means "*1000")

auto t = monotonic_clock::now(); // do something nanoseconds d = monotonic_clock::now() - t; // we want the result in nanoseconds cout << "something took " << d << "nanoseconds

";

auto t = monotonic_clock::now(); // do something auto d = monotonic_clock::now() - t; cout << "something took " << duration_cast<double>(d).count() << "seconds

";

See also

Standard: 20.9 Time utilities [time]

Howard E. Hinnant, Walter E. Brown, Jeff Garland, and Marc Paterno: A Foundation to Sleep On. N2661=08-0171. Including ``A Brief History of Time'' (With apologies to Stephen Hawking).

Atomics

See also

Standard: 29 Atomic operations library [atomics]

???

std::future and std::promise

The standard provides three kinds of futures, future for most simple uses, and shared_future and atomic_future for some trickier cases. Here, I'll just present future because it's the simplest and does all I need done. If we have a future<X> called f, we can get() a value of type X from it:

X v = f.get(); // if necessary wait for the value to get computed

We might not want to wait for a result, so we can ask the future if a result has arrived:

if (f.wait_for(0)) { // there is a value to get() // do something } else { // do something else }

The main purpose of promise is to provide a simple ``put'' (curiously, called ``set'') to match future's get(). The names ``future'' and ``promise'' are historical; please don't blame me. They are also a fertile source of puns.

If you have a promise and need to send a result of type X (back) to a future, there are basically two things you can do: pass a value and pass an exception:

try { X res; // compute a value for res p.set_value(res); } catch (...) { // oops: couldn't compute res p.set_exception(std::current_exception()); }

So far so good, but how do I get a matching future/promise pair, one in my thread and one in some other thread? Well, since futures and promises can be moved (not copied) around there is a wide variety of possibilities. The most obvious idea is for whoever wants a task done to create a thread and give the promise to it while keeping the corresponding future as the place for the result. Using async() is the most extreme/elegant variant of the latter technique.

The packaged_task type is provided to simplify launching a thread to execute a task. In particular, it takes care of setting up a future connected to a promise and to provides the wrapper code to put the return value or exception from the task into the promise. For example:

double comp(vector<double>& v) { // package the tasks: // (the task here is the standard accumulate() for an array of doubles): packaged_task<double(double*,double*,double)> pt0{std::accumulate<double*,double*,double>}; packaged_task<double(double*,double*,double)> pt1{std::accumulate<double*,double*,double>}; auto f0 = pt0.get_future(); // get hold of the futures auto f1 = pt1.get_future(); pt0(&v[0]