geniacllm/wiki40b huggingface dataset:
C++03 には、型の初期化に関して多くの問題点があった。初期化に複数の方法があり、しかもお互いを取り替えたときに同じ結果になるわけではなかった。例えば、従来のコンストラクタの構文は関数宣言と同じ形をしており、場合によってはコンパイラが正しく判定できないことがあった。また、初期化リストは集約型やPOD型にしか使うことができなかった。C++11 では、どんなオブジェクトでも初期化できる完全に統一的な記法 (uniform initialization) が導入された。これは初期化リスト構文の拡張である。struct BasicStruct {  int x;  double y;};struct AltStruct {  AltStruct(int x, double y) : x_(x), y_(y) {}  private:  int x_;  double y_;};BasicStruct var1{ 5, 3.2 };AltStruct var2{ 2, 4.3 };var1 の初期化は完全に C 形式の初期化子リストと同様に振る舞う。すなわち、各データメンバーは、初期化子リストのそれぞれの値によってコピー初期化される。必要ならば暗黙の型変換が行われ、型変換が不可能ならば、コンパイルに失敗する。var2 の初期化は、単純にコンストラクタを呼ぶだけである。型が明らかな場合、次のように書くこともできる。struct IdString {  std::string name;  int identifier;};IdString get_string(){  return { "SomeName", 4 }; // 明示的な型の指定は不要。}統一的な初期化構文は、必ずしもコンストラクタ構文の代用となるものではない。コンストラクタ構文が必要な場合もある。クラスが初期化子リストコンストラクタ(TypeName(std::initializer_list<SomeType>)) を持つような場合、（初期化子リストがシーケンスコンストラクタの型に適合するのならば）初期化子リストコンストラクタが優先して適用される。例えば、C++11 の std::vector は、そのテンプレート型の初期化子リストコンストラクタを持つ。つまり、std::vector<int> theVec { 4 };のように書いた場合、初期化子リストコンストラクタが呼ばれる。固定長の std::vector を生成するための、サイズを指定する引数ひとつを取るコンストラクタstd::vector(size_type n)を呼ぶためには、標準のコンストラクタ構文を使う必要がある。std::vector<int> theVec ( 4 );
C++03やCでは、変数の型は使用に際して明示的に指定しなければならない。しかし、テンプレート型やテンプレートメタプログラミングなどにおいては、特に関数の戻り値型が複雑に定義されているような場合、型を簡単に書き下せないことがある。そのような場合には、中間結果を変数に格納することが難しく、メタプログラミングライブラリの内部仕様を知っていなくてはならなくなる場合もある。C++11 では型推論により、この制約を軽減する方法が二つ提供された。一つ目の方法は、明示的に初期化される変数の定義に auto キーワードを使う方法である。これにより、初期化子によって変数の型が特定される。auto someStrangeCallableType = boost::bind(&SomeFunction, _2, _1, someObject);auto otherVariable = 5;someStrangeCallableType の型は、関数テンプレート boost::bind がその引数に応じて返す戻り値の型である。これはコンパイラにとっては容易に判別できるが、ユーザーが調べるのは困難である。otherVariable の型はまだ分かりやすい。これは、整数リテラルの型である int となる。二つ目の方法は、キーワード decltype である。これによって、オペランドで指定した式の型をコンパイル時に取得することができる。int someInt;decltype(someInt) otherIntegerVariable = 5;auto で宣言した変数の型はコンパイラにしか分からないので、decltype は auto と組み合わせて使うと特に有用である。auto はコードの冗長性を省くのにも有用である。例えば、以下のように書かれている場合、for (std::vector<int>::const_iterator itr = myvec.begin(); itr != myvec.end(); ++itr)autoを使えばもっと短く書くことができる。for (auto itr = myvec.begin(); itr != myvec.end(); ++itr)コンテナをネストして使うような場合、違いはもっと大きくなる。一方、そのような場合は typedef を使うこともできる。
C++03では、コンテナの要素を列挙するためには多くのコードを書く必要があった。一方C#やJavaのような言語には、コンテナの最初から最後までをたどるシンプルな「foreach文」が備わっている。C++11にも同様の機能が追加された。以下のようなfor文の別表現を使ってコンテナの要素を簡単に列挙することができる。int my_array[5] = {1, 2, 3, 4, 5};for (int& x : my_array) {    x *= 2;}この形式のfor文は、範囲に基づくfor (range-based for) と呼ばれる。この形式は、Cスタイルの配列や、初期化リスト、イテレータを返すbegin()関数とend()関数が定義されたあらゆる型に対して使うことができる。begin()とend()を持つ標準ライブラリのコンテナはすべてこの形式で列挙できる。
C++ 標準では、特に std::sort や std::find といった C++ 標準ライブラリのアルゴリズム関数と組み合わせた時に、アルゴリズム関数の呼び出しの近くで述語関数を定義したいと思う機会が多い。しかし、このためには関数内部でクラスを定義するしかなかった。この方法は記述量が多く、またコードの流れを妨げがちである。加えて、標準 C++ の規則では、関数の中で定義されたクラスをテンプレートの中で使うことを認めていないので、結局どうしても使うことは不可能であった。これに対して、C++11ではラムダ関数が定義できるようになった。ラムダ関数は以下のように定義される:[](int x, int y) -> int { int z = x + y; return z + x; }これは、int型の引数を二つとり、int型の値を返すラムダ式である。その内容は{ } の中に記述される。ラムダ関数の内容が "return 式" の形式である場合には、戻り値型を省略することができる。[](int x, int y) { return x + y; }このラムダ関数の戻り値型は decltype(x+y) になる。ラムダ関数が値を返さない場合、つまり戻り値型が void の場合も戻り値型を省略できる。ラムダ関数の外で定義された変数であっても、ラムダ関数の中で使用することができる。この種のものは一般にクロージャと呼ばれる。クロージャは[ ]の中に記述する。std::vector<int> someList;int total = 0;std::for_each(someList.begin(), someList.end(), [&total](int x) {  total += x;});std::cout << total;これは、リストの全要素の合計を表示する例である。変数 total がラムダ関数のクロージャの一部として格納される。これはスタック変数 total への参照なので、代入することで外側の total の値も変更される。& は参照を表すシンボルである。スタック変数に対応するクロージャ変数は、&を付けずに定義することも可能で、その場合はラムダ関数は値をコピーする。これにより、スタック変数を参照するのかコピーするのかどちらの意図があるのかわかるようになる。スタック変数を参照することは危険な場合がある。例えば (C++11 標準の) std::function オブジェクトに格納するなどして、ラムダ関数を生成したスコープの外側で使いたい場合は、ラムダ関数がスタック変数を参照していないことをよく確認する必要がある。ラムダ関数がその定義のあるスコープの内側で実行されることが保証されている場合は、次のように記述すれば、スタック変数をひとつひとつ指定せずに全ての利用可能なスタック変数を使用できる。std::vector<int> someList;int total = 0;std::for_each(someList.begin(), someList.end(), [&](int x) {  total += x;});[ ]の中には次のような指定が可能である。[]        // ラムダ関数外のどの変数も使うことができない。[x, &y]   // xはコピーされる。yは参照渡しされる。[&]       // すべての外部変数は、もし使われれば暗黙的に参照渡しされる。[=]       // すべての外部変数は、もし使われれば暗黙的にコピーされる。[&, x]    // xは明示的にコピーされる。その他の変数は参照渡しされる。[=, &z]   // zは明示的に参照渡しされる。その他の変数はコピーされる。また、ラムダ関数がクラスのメンバ関数により定義された場合、そのクラスのフレンドであると見なされる。そのようなラムダ関数は、そのクラス型のオブジェクトへの参照を使って、内部のメンバにアクセスできる。[](SomeType *typePtr) { typePtr->SomePrivateMemberFunction(); };この例は、このラムダ関数の生成するスコープが SomeType のメンバ関数の中にある場合にのみ動作する。this ポインタは、各時点でメンバ関数が作動しているオブジェクトを指しているが、その扱いは特別である。ラムダ関数中に明示的な指定が必要になる。 [this]() { this->SomePrivateMemberFunction(); }; [&] または [=] 形式のラムダ関数を用いていれば、thisの記述は必要ない。ラムダ関数の型はコンパイラ依存であり、明示的に記述することはできない。ラムダ関数を引数として取得したい場合は、その型をテンプレート型にするか、std::function などの型消去の仕組みを使う必要がある。auto キーワードを使ってラムダ関数をローカル変数に格納することはできる。auto myLambdaFunc = [this]() { this->SomePrivateMemberFunction(); };
標準Cの関数宣言の構文はC言語の機能に対しては最適なものであった。C++ は C から離れて発展してきたが、その基本的な構文を維持しつつ、必要に応じて拡張してきた。しかし、C++ がさらに複雑になってくると、多数の制約、特にテンプレート関数の宣言に関する制約が露呈するようになった。例えば、次の書き方は C++03 では認められていない。// 正しくないtemplate<typename LHS, typename RHS>   Ret AddingFunc(const LHS& lhs, const RHS& rhs) { return lhs + rhs; }Ret 型は、LHS と RHS の型を加算して作られる型であり、それらの実際の型によって決まる。前述の decltype という C++11 の機能を使うこともできない。// 正しくないtemplate<typename LHS, typename RHS>   decltype(lhs+rhs) AddingFunc(const LHS& lhs, const RHS& rhs) { return lhs + rhs; }パーサーが decltype(lhs+rhs) を解析する時点で、lhs と rhs はまだ定義されておらず、有効な識別子にはなっていない。したがって、この書き方も C++ に適合していない。この問題に対処するために、C++11 では次のような関数の定義と宣言の構文が導入された。template<typename LHS, typename RHS>   auto AddingFunc(const LHS& lhs, const RHS& rhs) -> decltype(lhs+rhs) { return lhs + rhs; }この構文は、非テンプレート関数の宣言や定義にも使用できる。struct SomeStruct {  auto FuncName(int x, int y) -> int;}; auto SomeStruct::FuncName(int x, int y) -> int {  return x + y;}この構文で使われるautoキーワードは、自動型推論の場合とは異なった意味をもつ。
C++03では、コンストラクタは他のコンストラクタを呼び出せず、各コンストラクタでクラスメンバの初期化を全て行わなくてはならない。これはしばしば初期化コードの重複を招く。また、基底クラスのコンストラクタは、派生クラスに直接は公開されない。つまり、基底クラスのコンストラクタと殆ど同等であったとしても、派生クラス側でコンストラクタを定義する必要がある。他にも、constでないデータメンバは、メンバの宣言時に初期化できず、コンストラクタで初期化しなければならない。C++11では、このような問題点に対する解決策が提供された。まず、C++11では、コンストラクタが他の同等なコンストラクタを呼び出すこと（委譲）が可能になった。これにより、コンストラクタが他のコンストラクタを最小のコード追加で利用できるようになる。他の言語（Java等）では、既にこれを取り入れているものもある。構文は以下のようになる:class SomeType {  int number;  public:  SomeType(int newNumber) : number(newNumber) {}  SomeType() : SomeType(42) {}};注意すべき点として、C++03では1つのコンストラクタの動作完了と同時にオブジェクトの構築は完了していると考えることができていたが、C++11では一度のオブジェクトの構築に全てのコンストラクタが動作完了しなければならない、と考えなくてはならない点である。複数のコンストラクタが動作することを認めるので、委譲を行う各コンストラクタは完全に構築が完了したオブジェクトに対して動作することを意味する。派生クラスのコンストラクタは、基底クラスでのコンストラクタ間委譲が全て終了した時点で呼び出されることになるであろう。次に基底クラスのコンストラクタに関して、C++11では、基底クラスのコンストラクタを継承するようにクラスに対して指定することが可能になる。これにより、コンパイラは派生クラスのコンストラクタ呼び出しを基底クラスのそれへと転送するコードを生成することになる。注意すべき点は、この機能は、全てのコンストラクタ呼び出しを基底クラスに転送するか、全く転送しないか、の二者択一の機能であることである。他の注意点として、多重継承時の制限もある。同じシグネチャを持つ2つのコンストラクタに転送することはできないし、転送先のコンストラクタと同じシグネチャを持つコンストラクタを後で宣言することはできない。構文は以下のようになる:class BaseClass {public:  BaseClass(int value);  BaseClass(float value);};class DerivedClass : public BaseClass {public:  using BaseClass::BaseClass;};最後にメンバの初期化に関して、C++11では、メンバの初期化に以下のような構文が認められる:class SomeClass {  int iValue = 5;};この例では、コンストラクタが初期化内容を上書きしない限り、iValueは5に初期化される。上書きする例は次のようになる:class SomeClass {  int iValue = 5;  public:  SomeClass() {}  explicit SomeClass(int iNewValue) : iValue(iNewValue) {}};この場合、空のコンストラクタではiValueはクラス定義に従って初期化されるが、int引数を取るコンストラクタの場合はその引数に従って初期化されることになるであろう。
C++03では、ユーザーが基底クラスの仮想関数をオーバーライドする際、誤って意図に反する新しい仮想関数を作成する可能性がある:struct Base {  virtual void some_func(float);  virtual bool on_error();};struct Derived : Base {  virtual void some_func(int);  virtual bool on_eror();};派生クラスDerivedを設計したユーザーは、Base::some_funcおよびBase::on_errorをオーバーライドするつもりで記述したが、それぞれ引数の型や関数名（シグネチャ）が異なるため新しい仮想関数が生成される。上記はC++コードとして誤りではないためコンパイルエラーにならず、間違いに気付くことができない。C++11では、overrideキーワードの導入により、このような問題が解消された:struct Base {  virtual void some_func(float);  virtual bool on_error();};struct Derived : Base {  virtual void some_func(int) override; // 不正：基底クラスの仮想関数をオーバーライドしていない。  virtual bool on_eror() override; // 不正：同上。};overrideキーワードで修飾された仮想関数が、基底クラスのオーバーライド先と一致するかどうかをコンパイラがチェックし、一致しない場合にエラーを報告する。overrideの他にfinalキーワードがある。finalで修飾された仮想関数のオーバーライドは許可されない。struct Base {  virtual void f() const final;};struct Derived : Base {  void f() const; // エラー：Derived::fがfinal Base::fをオーバーライドしようとする。};
C++03では、定数0に、整数定数とヌルポインタという2つの役割が与えられている（この振る舞いは、Cの黎明期（1972年）から続いている）。長い間プログラマは、0の代わりに定数NULLを使って、この潜在的な曖昧性を大体は回避してきた。しかし、C++になされた2つの設計上の選択が、新たな曖昧性をもたらした。Cでは、NULLはプリプロセッサマクロであり、((void*)0)か0と展開されるよう定義されている。C++では、void*型から他のポインタ型への暗黙の変換は認められないので、Cの1つ目の定義と同じくNULLを定義すると、char *c = NULLのような単純な例でもコンパイルエラーになる。これを修正するため、C++ではNULLは0へと展開される。0は、あらゆるポインタ型への変換が特別に認められているのである。この結果、オーバーロード機構と酷い相互作用を引き起こす。例えば、以下のような宣言がありvoid foo(char *);void foo(int);foo(NULL)として呼び出す場合、foo(int)の方が呼ばれることになる。この挙動は、多くの場合に意図されたものではない。新標準では、ヌルポインタを指定するためにのみ予約された新たなキーワードnullptrが導入される。nullptrは整数型との比較や代入はできないが、あらゆるポインタ型との比較・代入ができる。互換性のため、0の現行の機能も残されるが、この新構文が上手くいけば、C++委員会は0とNULLをヌルポインタとして使用することを非推奨と宣言し、意味の重複を排除するであろう。
C++03では、列挙型は型安全でなかった。列挙型が異なっていても、実質的には整数として扱われていた。このため、型の違う列挙型の値同士が比較できてしまった。C++03で唯一提供されていた型安全性は、整数や、ある列挙型の値が、暗黙的に他の列挙型には変換されない、ということだけである。また、内部的な整数型はコンパイラの実装に依存しており、列挙型のサイズに依存するコードは可搬ではなかった。さらに、列挙型の値のスコープは、列挙体が定義されたスコープと同じとなる。そのため、二つの列挙型が、同じ名前のメンバをもつことはできなかった。C++11では、以上のような問題のない、特別なクラス化された列挙型が導入された。enum class（またはenum struct）宣言を用いることで、これを表現できる。enum class Enumeration {  Val1,  Val2,  Val3 = 100,  Val4 /* = 101 */,};この列挙は型安全である。enum classの値が暗黙的に整数値に変換されることはなく、したがって整数値と比較することもできない（Enumeration::Val4 == 101はコンパイルエラーになる）。enum classの内部的な型はコンパイラの実装に依存しない。デフォルトではintであり、次のように明示的に指定することもできる。enum class Enum2 : unsigned int {Val1, Val2};列挙名は列挙型のスコープで定義される。列挙名を使うときには、Enum2::Val1のように明示的にスコープを指定しなければならない。上の例では、Val1は未定義である。さらに、C++11では従来スタイルの列挙型にも、明示的なスコープや内部的な型の指定ができる。enum Enum3 : unsigned long {Val1 = 1, Val2};この場合、列挙名は列挙型のスコープで定義される（Enum3::Val1）が、後方互換性のため、列挙型が定義されたスコープにも定義される（Val1）。C++11では列挙型の前方宣言も可能である。以前は列挙型のサイズが内容によって決まっていたため、列挙型は前方宣言できなかった。明示的あるいは暗黙的に列挙のサイズが決定できさえすれば、前方宣言が可能である。enum Enum1;                     // C++03とC++11両方で不正。内部的な型が明示されていない。enum Enum2 : unsigned int;      // C++11では正しい。内部的な型が明示されている。enum class Enum3;               // C++11では正しい。enum class宣言はデフォルトの型がintである。enum class Enum4: unsigned int; // C++11では正しい。enum Enum2 : unsigned short;    // C++11でも不正。Enum2が既に違う型で宣言されている。
テンプレートを用いた総称プログラミングを導入するのに、新形式の括弧を導入するのが必要であった。そのためC++には、丸括弧"()"、角括弧"[]"、波括弧"{}"に加えて、山括弧"<>"が導入された。しかし、これにより字句的曖昧さが生じ、（プログラマの意図とは違う、という意味で）間違って解析され、構文エラーになるという事態が発生した:typedef std::vector<std::vector<int> > Table;  // OK。typedef std::vector<std::vector<bool>> Flags;  // エラー！ ">>"は右シフトと解析される。 void func(List<B>= default_val);  // エラー！ ">="は比較演算子と解析される。void func(List<List<B>>= default_val);  // エラー！ ">>="は右シフト代入と解析される。 template<bool I> class X {};X<(1>2)> x1;  // OK。X< 1>2 > x1;  // エラー！ 一つ目の">"は山閉じ括弧と解析される。C++11の字句解析では、最も深くネストした開き括弧が山括弧"<"である場合、">"は、次に">"や"="が続いていても山閉じ括弧として扱われる。これにより、上記のエラーは最後のものを除いて修正される。最後のものを修正するには、曖昧さを取り除くために丸括弧を足さなくてはならない。X<(1>2)> x1;  // OK。こうすることで、"("から")"の間については、コンパイラは<>の文字を山括弧と扱わなくなる。
C++規格には、一引数コンストラクタを暗黙的な型変換関数として扱われないようにするための修飾子として、explicitキーワードが導入された。しかし、これは変換関数には何の効果も無い。例えば、スマートポインタのクラスは、本物のポインタと同じように振る舞うためにoperator bool()を持っていることがある。この変換を追加することで、if (smart_ptr_variable)としてそれをテストできる（ポインタが非NULLならtrueを、NULLならfalseと判定できるはずである）。しかし、この変換を認めると、不本意な変換も発生してしまう。C++のboolは算術型として定義されているため、整数型やさらには浮動小数点型としてまで変換されてしまい、ユーザーが意図しない数値型としての動作を引き起こしてしまうのである。C++11では、explicitキーワードを変換関数にも適用できるようになる。コンストラクタへの適用と組み合わせ、さらなる暗黙的型変換を防止できる。
C++03では、typedefを定義する際にできることは、他の型に対して別名を付けることだけであり、存在するすべてのテンプレート引数が指定されたテンプレートの特殊化に対して別名をつけることもこれに含まれる。typedefのテンプレートを作ることはできない。例えば:template <typename First, typename Second, int Third>class SomeType;template <typename Second>typedef SomeType<OtherType, Second, 5> TypedefName; // C++03では不正これはコンパイルできない。C++11では以下の構文でこれが可能になった。template <typename First, typename Second, int Third>class SomeType;template <typename Second>using TypedefName = SomeType<OtherType, Second, 5>;C++11ではusing構文は型の別名付けにも使用できる。typedef void (*Type)(double); // 従来の形式using OtherType = void (*)(double); // 新たに導入された形式
C++11には、透過的ガベージコレクションの機能は直接には導入されない。代わりに、C++11標準には、C++でのガベージコレクションの実装を容易にする仕様が導入された。完全なガベージコレクションのサポートは、もっと後の標準やTechnical Reportに回されることになった。
C++標準にはunionのメンバになれるオブジェクトの型に対する制限がある。例えば、trivialでないコンストラクタが定義されているオブジェクトは共用体の中に含めることが不可能である。共用体に課された制限の多くは無くてもよいと考えられたため、次期標準では参照型を除いて共用体のメンバの型の制限が全廃される。この変更により、共用体は使いやすく強力で有用なものになる。以下はC++11で許される共用体の簡単な例である:struct point {  point() {}  point(int x, int y): x_(x), y_(y) {}  int x_, y_;};union {  int z;  double w;  point p;  // pointがtrivialでないコンストラクタを持つためC++03では不正だが、C++11では問題ない。};この変更は現行の規則を緩めるだけなので、既存のコードを破壊することはない。
C++03のテンプレート（クラステンプレート・関数テンプレート）は、あらかじめ決められた個数の引数しか取れない。C++11では、テンプレート定義の際にあらゆる型の引数を任意個数取れる可変長引数テンプレート (variadic template) をサポートする:template<typename... Types> class tuple;このtupleクラステンプレートは、テンプレート引数としていくらでも型名を取れる:tuple<std::vector<int>, std::map<std::string, std::vector<int>>> someTuple; // tuple インスタンス。tuple<> emptyTuple; // 引数の数が0の場合。上記のクラステンプレートはstd::tupleとして標準化されている。可変長テンプレート引数の個数に0を認めない場合は、以下のように定義すればよい:template<typename First, typename... Rest>class tuple;可変長テンプレート引数を取る関数も定義でき、Cの可変長引数機構に似ているが、型安全な仕組みがもたらされる。template<typename... Params>void printf(const std::string& strFormat, Params... parameters);テンプレート定義時にはParamsの左側に...演算子を配置するが、関数シグネチャ中ではParamsの右側に使うことを注意する必要がある。テンプレート引数仕様のように、...演算子を型名の左側におく場合、これは"pack"演算子となる。この演算子は、型が0個以上となり得ることを示す。...演算子が型名の右側にある場合は、"unpack"演算子であり、pack演算子でまとめられた型のそれぞれに対して、複製の処理が行われるようになる。上の例では、printf関数の引数にはParamsにそれぞれの型がまとめられて渡される。可変長テンプレート引数自体は関数・クラスの実装に使えるものではないため、可変長引数テンプレートの使用は再帰的に行われる。例えば、典型的な例として、C++11におけるprintfの代替の定義例を以下に挙げてみよう:void printf(const char *s){  while (*s) {    if (*s == '%' && *(++s) != '%')      throw std::runtime_error("invalid format string: missing arguments");    std::cout << *s++;  }}template<typename T, typename... Args>void printf(const char *s, T value, Args... args){  while (*s) {    if (*s == '%' && *(++s) != '%') {      std::cout << value;      printf(*s ? ++s : s, args...); // さらなる引数を見つけるため、*s == '\0' でも呼び出す      return;    }    std::cout << *s++;  }  throw std::runtime_error("extra arguments provided to printf");}これは再帰呼び出しを使っている。可変長テンプレート引数バージョンのprintfは自身を再帰的に呼び出し、argsが空の場合はシンプルな方のprintfが呼ばれることになる。可変長テンプレート引数に順次アクセスする簡単な方法は無い。しかし、unpack演算子を用いることで、どこでも仮想的にテンプレート引数を解体できる。例えば、クラスを以下のように使用できる:template <typename... BaseClasses>class ClassName : public BaseClasses... {public:   ClassName (BaseClasses&&... baseClasses) : BaseClasses(static_cast<BaseClasses&&>(baseClasses))... {}}unpack演算子により、ClassNameの各基底クラス型が複製され、このクラスは渡された各型の導出クラスとなる。また、ClassNameの基底型を初期化できるように、コンストラクタは各基底クラスへの参照を取る。関数テンプレートでは、取った可変長引数を先へと転送できる。右辺値参照と組み合わせることで、完璧な転送が行える。template<typename TypeToConstruct>struct SharedPtrAllocator {  template<typename ...Args> tr1::shared_ptr<TypeToConstruct> ConstructWithSharedPtr(Args&&... params)  {    return tr1::shared_ptr<TypeToConstruct>(new TypeToConstruct(static_cast<Args&&>(params)...));  }}この特殊なファクトリ関数は、メモリリークに対する安全性のため、割り当てられたメモリをtr1::shared_ptrに自動的に包むものである。上記のように、引数リストを解体してTypeToConstructのコンストラクタへと渡している。static_cast<Args&&>(params)構文で、const性などを保ちつつ、引数の適切な型をコンストラクタへと転送できる。unpack演算子により、それぞれのパラメータに上記の伝播文法を適用できる。また、テンプレートパラメータの数を以下のように決定できる:template<typename ...Args> struct SomeStruct {  static const int size = sizeof...(Args);}SomeStruct<Type1, Type2>::sizeは2となり、SomeStruct<>::sizeは0となるであろう。
C++03には2種類の文字列リテラルがある。1つ目は、ヌル終端されたconst char型配列を生成する、ダブルクォーテーションで囲まれた形式のものである。2つ目は、ヌル終端されたconst wchar_t型配列（ワイド文字列）を生成する、Lプレフィックスを付けたダブルクォーテーションで囲まれた形式のものである。しかし、どちらもUnicodeで符号化された文字列リテラルを標準サポートするものではない。C++コンパイラでのUnicodeサポートを強化するため、char型の定義が修正され、少なくとも8ビット符号単位のUTF-8符号化形式を格納できて、コンパイラの基本実行文字セットのあらゆる文字を格納するのに十分な大きさを持つ、とされた。以前は後者だけを満たしていれば良いとされていた。C++11では、UTF-8, UTF-16, UTF-32の3つのUnicode符号化形式がサポートされる。先ほど述べたcharの定義の変更に加え、C++11には2つの新たな文字型、char16_tとchar32_tが加わる。それぞれ、UTF-16、UTF-32の符号単位を格納するよう設計されている。以下に、それぞれの符号化形式で文字列リテラルを作る方法を示す:u8"I'm a UTF-8 string.";u"This is a UTF-16 string.";U"This is a UTF-32 string.";1つ目の文字列の型は、普通のconst char *である。2つ目は、const char16_t*であり、3つ目はconst char32_t*となる。Unicode文字列リテラルを作るときには、Unicodeの符号位置を直接に文字列に埋め込めると便利である。C++11では、以下のような構文が使えるようになる:u8"This is a Unicode Character: \u2018.";u"This is a bigger Unicode Character: \u2018.";U"This is a Unicode Character: \u2018.";'\u'の後の数字は16進数であり、接頭辞'0x'をつける必要は無い。'\u'は16ビットのUnicode符号位置を示すものであり、32ビットのUnicode符号位置を示す場合は'\U'と16進数を用いる。正当なUnicode符号位置のみが入力できる。例えば、UTF-16のサロゲートペア（代用対）のために予約された、0xD800–0xDFFFの範囲の代用符号位置は使用できない。XMLファイルのリテラルを用いる場合や、正規表現のパターン文字列あるいはスクリプト言語のリテラルを用いる場合など、手動でエスケープしなくてよい文字列も有用である。C++11では、raw文字列リテラルが導入される:R"(The String Data \ Stuff " )";R"delimiter(The String Data \ Stuff " )delimiter";1つ目の場合、()括弧記号で挟まれた箇所全てが文字列となる。"や\の文字はエスケープする必要は無い。2つ目の場合、"delimiter(から)delimiter"までが文字列となる。delimiterという文字列は、実際には任意の文字列でよい。これにより、文字)をraw文字列リテラルで使用できるようになる。raw文字列リテラルは、ワイドリテラルや各種Unicodeリテラルと組み合わせて利用できる。
他の多くの言語と同様、C++03にも数種のリテラル値がある。例えば、"12.5"はコンパイラがdouble型の浮動小数点値へと変換するリテラル値である。しかし、リテラル値にはいくつもの修飾子がある。"12.5f"というリテラルは、浮動小数点値ではあるがfloat型の値を生成するように伝える。このような修飾子はC++仕様として規定されており、C++のコード中では新たな修飾子を生成することは不可能であった。C++11では、ユーザーが新たな種類のリテラル修飾子を定義できるようにし、リテラル修飾子の文字列を基にオブジェクトを生成できるようになる。リテラルの変換過程が再定義され、二つの段階、rawとcookedへと分けられた。rawリテラルは特定の型の文字の並びであり、cookedリテラルは単一の型である。例えば、C++リテラルの1234は、rawリテラルとしては'1', '2', '3', '4'という文字の並びであり、cookedリテラルとしては整数値1234である。0xAは、rawリテラルとしては'0', 'x', 'A'であり、cookedリテラルとしては整数値10である。常にcooked形式として処理される文字列リテラルを除き、リテラルはraw形式にもcooked形式にも拡張される。文字列リテラルが例外なのは、文字列には、文字列の型と特別な意味の指定を行う接頭辞があるからである。ユーザー定義リテラルは全て接尾辞である。接頭辞リテラルを定義することはできない。raw形式のリテラルを処理するユーザー定義リテラルは、以下のように定義できる:OutputType operator""_Suffix(const char *literal_string);OutputType someVariable = 1234_Suffix; // operator""_Suffix("1234") と等価1つ目の文で、接尾辞「_Suffix」を定義している。ユーザーが定義する接尾辞はアンダースコアで始める（アンダースコアで始まらないものは将来の標準のために予約されている）。2つ目の文では、ユーザー定義リテラル関数によって定義されたコードを実行している。この関数には、Cスタイルの文字列としてヌル終端された"1234"が渡される。rawリテラルを処理するもう1つの方法は、可変長引数テンプレートを使うことである:template<char...> OutputType operator""_Suffix();OutputType someVariable = 1234_Suffix;これにより、operator""_Suffix<'1', '2', '3', '4'>としてリテラル処理関数が実体化される。この形式では、文字列のヌル終端文字は無い。これを行う主目的は、C++11のconstexprを使い、OutputTypeをconstexprで構築可能かつコピー可能とし、リテラル処理関数をconstexpr関数とすることで、コンパイラにリテラルの変換を完全にコンパイル時に行わせることである。cookedリテラルの場合は、cookedリテラルの型が使われ、代替となるテンプレート形式は無い:OutputType operator""_Suffix(int the_value);OutputType someVariable = 1234_Suffix;文字列リテラルの場合、以下のものが使用でき、前述の新たな文字列接頭辞と組み合わせられる:OutputType operator""_Suffix(const char * string_values, size_t num_chars);OutputType operator""_Suffix(const wchar_t * string_values, size_t num_chars);OutputType operator""_Suffix(const char16_t * string_values, size_t num_chars);OutputType operator""_Suffix(const char32_t * string_values, size_t num_chars);OutputType someVariable = "1234"_Suffix;      //const char * バージョンを呼び出すOutputType someVariable = u8"1234"_Suffix;    //const char * バージョンを呼び出すOutputType someVariable = L"1234"_Suffix;     //const wchar_t * バージョンを呼び出すOutputType someVariable = u"1234"_Suffix;     //const char16_t * バージョンを呼び出すOutputType someVariable = U"1234"_Suffix;     //const char32_t * バージョンを呼び出す文字リテラルも同様に定義できる。
C++標準化委員会はマルチスレッドの標準的サポートの導入を計画している。これには2つの側面がある。つまり、複数スレッドが1つのプログラム中で共存できるメモリモデルを定義することと、スレッド間相互作用のサポートを定義することである。2つ目に関してはライブラリによって提供される。#スレッディングを参照のこと。複数のスレッドが同じメモリ位置にアクセスする可能性がある環境下でのプログラム記述には、メモリモデルが必要となる。つまり、ルールを遵守するプログラムは正しく実行されるであろうと思われるが、ルールに従わないプログラムはコンパイラの最適化に依存する未定義の振る舞いや、memory coherenceの問題を抱えることになる。
マルチスレッド環境においては、各スレッドごとに独立した変数（スレッドローカルストレージ、TLS）が必要となることがある。C++03では、関数内のローカル変数（自動変数）はこのような変数に該当するが、グローバル変数、また静的変数としては標準化されていない。各種コンパイラはそれぞれ独自拡張を用意してTLSに対応していた。C++11では、新たなスレッドローカル記憶クラスが、（既存のstatic、動的、autoに加えて）新たに追加された。スレッドローカル記憶域は、記憶クラス指定子 thread_localによって指定する。スレッドローカル記憶クラスは、static記憶クラスを持ち得るあらゆるオブジェクト（プログラムの実行期間全体にわたって存在しているようなもの）にも付けられるだろう。つまり、スレッドローカルなオブジェクトは、static記憶クラスの変数と同様のやり方で、コンストラクタで初期化されデストラクタで破壊されるということである。
C++03では、オブジェクトにコンストラクタ、コピーコンストラクタ、代入演算子 (operator=)、そしてデストラクタが与えられていない場合、コンパイラが自動的にそれらを提供する。ユーザーは自身のバージョンを定義することで、デフォルトの動作を上書きできる。また、C++は全てのクラスに適用されるグローバルな演算子（operator=やoperator new）も提供しており、その動作もユーザーが上書きできる。しかし、デフォルトで作られる関数の生成を制御する方法が非常に少ないという問題がある。例えば、クラスを実質的にコピー不能にするには、コピーコンストラクタと代入演算子をprivateとして宣言し、定義しないことによって実現できる。これらの関数を使用しようとすると、コンパイラやリンカがエラーを報告するようになるというわけである。しかし、これは理想的な解法とはいえないであろう。さらに言えば、例えばデフォルトコンストラクタなど、コンパイラに対して明示的に生成するよう伝えておくことも有用である。オブジェクトに「どんなものであれ一つでも」コンストラクタが定義されているのであれば、コンパイラはデフォルトコンストラクタを生成しない。また、特別なコンストラクタとコンパイラが生成するデフォルトとを両方持っておくことも有用な場面がある。C++11では、これらコンパイラが生成する関数の使用・不使用を明示できるようになる。例えば、以下のクラスはデフォルトコンストラクタの使用を明示している:struct SomeType {  SomeType() = default; // デフォルトコンストラクタが明示される  SomeType(OtherType value);};また逆に、明示的に無効にすることも可能である。以下の例はコピー不能な型の例である:struct NonCopyable {  NonCopyable& operator=(const NonCopyable&) = delete;  NonCopyable(const NonCopyable&) = delete;  NonCopyable() = default;};new演算子で割り当てられないようにすることもできる:struct NonNewable {  void *operator new(std::size_t) = delete;};このオブジェクトは、スタック上か、他の型のメンバとしてしか割り付けられない。移植性の無いトリックを使いでもしない限り、直接ヒープには割り当てられないのである（ユーザー割り当てのメモリ上にコンストラクタを呼ぶ方法は配置newしかなく、その使用は上記のように禁じられているので、オブジェクトは適切に構築できない）。= deleteという指定は、どんな関数の呼び出しも禁止できる。これは、メンバ関数を特定の型で呼び出すのを禁止するのに使える。例えば:struct NoDouble {  void f(int i);  void f(double) = delete;};doubleでf()を呼ぼうとすると、暗黙のintへの変換を行うのではなく、コンパイラによってエラーになる。以下のようにすることで、int型以外の型では呼べないようにする総称化ができる:struct NoDouble {  void f(int i);  template<class T> void f(T) = delete;};
C++標準には、表明を確認する2つの方法として、assertマクロと#errorプリプロセッサディレクティブがある。しかし、このどちらもテンプレート使用時には不適切である。assertマクロでの確認は実行時であり、#errorプリプロセッサディレクティブでの確認はプリプロセス時である。どちらもテンプレート実体化時の確認には使えないため、テンプレート引数に依存する特性の検証には適していない。そこで、コンパイル時点での表明確認の新たな手法として新たなキーワードであるstatic_assertが導入される。宣言は以下のような形になるであろう:static_assert( ''constant-expression'', ''error-message'' );以下に、static_assertの使用法の例を挙げる:static_assert(3.14 < GREEKPI && GREEKPI < 3.15, " GREEKPI is inaccurate!");template<typename T>struct Check {  static_assert(sizeof(int) <= sizeof(T), "T is not big enough!");};constant-expressionがfalseとなる場合、コンパイラはエラーメッセージを生成する。1つ目の例は#errorプリプロセッサディレクティブの代替の例である。2つ目の例の方は、Checkクラステンプレートの各実体化において表明の確認をしている。静的な表明はテンプレート以外での使用も有益である。例えば、long longがintより大きいサイズであることに依存するアルゴリズムの実装のように、標準では保障されていない箇所の確認などの用途がある（このような仮定はほとんどのシステム、コンパイラで正しいだろうが、全ての環境で正しいとは言えない）。
C++03では、sizeof演算子は型とオブジェクトに対してしか適用できない。そのため、以下のようには使用できない:struct SomeType { OtherType member; };size_t memberSize = sizeof(SomeType::member); // C++03では動かない。この例では、OtherTypeのサイズを取得したい場面であるが、C++03ではこれは不正となりコンパイルエラーとなる。C++11では認められる。ちなみに、C++03で同様のことをしたい場合、以下のようにすればよい:struct SomeType { OtherType member; };size_t memberSize = sizeof(static_cast<SomeType*>(0)->member);
大量の新機能が、C++11標準ライブラリに追加される。新しいライブラリの多くは現行の標準規格で実装できるが、C++11のコア言語の新機能に（程度の差はあれど）依存しているものもある。導入されるライブラリの大部分は、C++ Standards Committee's Library Technical Report（TR1と呼ばれる）の文書で定義されている。TR1の最終稿は、2005年に出されている。なお、TR1の多くはBoost C++ライブラリが基になっている。TR1ライブラリの実装は既に数種類が利用可能であり、std::tr1名前空間を用いて呼び出せる。C++11ではstd名前空間に移動される。委員会は、2つ目のTechnical Report (C++ Technical Report 2) をC++11の標準化後に予定している。C++11に間に合わないライブラリ提案は、TR2や、さらに先のTechnical Reportに置かれることになる。以下の提案は、C++11に搭載されることが予定されているものである。
スレッドクラスにより、関数オブジェクトを元に新たなスレッドの起動が可能になる。各時点において、あるスレッドが実行中のスレッドへのjoin（スレッドの終了を待つこと）も可能である。（可能であれば）ネイティブスレッドオブジェクトにアクセスし、プラットフォーム固有の操作を行うことも可能となるだろう。スレッド間の同期のためにミューテックスや条件変数がライブラリに追加され、RAII方式のロックやロックアルゴリズムの使用も容易になる。低レベル処理の高効率性のためには、スレッド間通信をミューテックスのオーバーヘッドなしで行う機能も必要となる。これは、適切なメモリバリアと不可分操作を用いることで達成できる。不可分操作ライブラリにより、各操作を行うのに必要な最小限の同期だけを指定できる。スレッドプールのような高レベルスレッディング用のライブラリも作業中であるが、C++11標準にすべて搭載されてはいない。C++11では主に基礎となるライブラリが定義され、将来のTechnical Reportに含まれることが望まれる。
コンピュータは決定的な振る舞いをするものであるが、疑似乱数による乱数列を生成することにより、（外見だけでも）非決定的な振る舞いが必要となるようなアプリケーションがある。標準に用意されている方法は、rand関数のみである。しかし、十分な定義がされていないため、そのアルゴリズムは完全にライブラリ開発者に任せられている。新たな乱数生成ユーティリティは<random>ヘッダを通して定義される。他のヘッダやC++言語への修正は必要としない。乱数生成器は、内部状態と、結果を計算し次の状態を生成するための関数をもつ。この2つの特性によって、乱数生成エンジンが定まる。他の特性として、生成結果や乱数の間隔や密度の分布も重要である。
random_deviceクラスを用いて、unsigned int型の非決定的乱数を生成できる。実装には、システムから独立した入力を持つデバイス（例えば、非同期的な外部カウンタや、特殊なトランスデューサーなど）の使用や、伝統的な「結果を調節する」擬似乱数エンジンの使用が必要である。libstdc++やlibc++では、/dev/urandomを読み出す実装となっている。
参照ラッパはテンプレートクラスstd::reference_wrapperのインスタンスとして得られる。参照ラッパは、C++言語の通常のリファレンス ('&') にも似ている。オブジェクトから参照ラッパを得るには、テンプレート関数std::refを使う（constな参照の場合はstd::crefが使用される）。参照ラッパはテンプレート関数と使用する場合に有用であり、特に引数としてコピーではなく参照を取る必要がある場合に便利である:#include <iostream>#include <functional>// 引数 r として int への参照を受け取り、それを増加させる関数。void inc(int& r) {  r++;}// 関数を呼び出す高階関数テンプレート。template<class F, class P>void invoke(F f, P t) { f(t); }int main() {  int i = 0;  invoke(inc, i);  // invoke<void(int& r), int> が実体化される。  // よって i の値は変更されない。  std::cout << i << std::endl; // 0 が出力される。  invoke(inc, std::ref(i));  // invoke<void(int& r), std::reference_wrapper<int>> が実体化される。  // よって i の値が変更される。  std::cout << i << std::endl; // 1 が出力される。  return 0;}この新ユーティリティは現在の<utility>に追加される。C++言語の拡張は必要としない。なお、上記の高階関数テンプレートは、のちにC++17にて可変長引数テンプレートstd::invokeとして標準化されている。