C++11
非 trivial なコピー代入演算子を持たない。
非 trivial なムーブ代入演算子を持たない。
trivial なデストラクタを持つ。
standard-layout なクラス・構造体は、以下のように定義される。
全ての非静的データメンバが standard-layout 型である。
全ての非静的データメンバに、同じアクセス制御 (public, private, protected) がかかっている。
仮想関数を持たない。
仮想基底クラスを持たない。
全ての基底クラスが standard-layout 型である。
一つ目に定義された非静的データメンバと同じ型の基底クラスを持たない。
非静的データメンバを持つ基底クラスを持たない。もしくは、導出クラスが非静的データメンバを持たず、高々一つの基底クラスしか非静的データメンバを持たない。これはつまり、クラス階層において非静的データメンバを持ってよいクラスは一つだけである、ということである。
C++03では、列挙型は型安全でなかった。列挙型が異なっていても、実質的には整数として扱われていた。このため、型の違う列挙型の値同士が比較できてしまった。C++03で唯一提供されていた型安全性は、整数や、ある列挙型の値が、暗黙的に他の列挙型には変換されない、ということだけである。また、内部的な整数型はコンパイラの実装に依存しており、列挙型のサイズに依存するコードは可搬ではなかった。さらに、列挙型の値のスコープは、列挙体が定義されたスコープと同じとなる。そのため、二つの列挙型が、同じ名前のメンバをもつことはできなかった。
C++11では、以上のような問題のない、特別なクラス化された列挙型が導入された。enum class(またはenum struct)宣言を用いることで、これを表現できる。
この列挙は型安全である。enum classの値が暗黙的に整数値に変換されることはなく、したがって整数値と比較することもできない(Enumeration::Val4 == 101はコンパイルエラーになる)。
C++03のテンプレート(クラステンプレート・関数テンプレート)は、あらかじめ決められた個数の引数しか取れない。C++11では、テンプレート定義の際にあらゆる型の引数を任意個数取れる可変長引数テンプレート (variadic template) をサポートする:
このtupleクラステンプレートは、テンプレート引数としていくらでも型名を取れる:
上記のクラステンプレートはstd::tupleとして標準化されている。
可変長テンプレート引数の個数に0を認めない場合は、以下のように定義すればよい:
可変長テンプレート引数を取る関数も定義でき、Cの可変長引数機構に似ているが、型安全な仕組みがもたらされる。
テンプレート定義時にはParamsの左側に...演算子を配置するが、関数シグネチャ中ではParamsの右側に使うことを注意する必要がある。テンプレート引数仕様のように、...演算子を型名の左側におく場合、これは"pack"演算子となる。この演算子は、型が0個以上となり得ることを示す。...演算子が型名の右側にある場合は、"unpack"演算子であり、pack演算子でまとめられた型のそれぞれに対して、複製の処理が行われるようになる。上の例では、printf関数の引数にはParamsにそれぞれの型がまとめられて渡される。
可変長テンプレート引数自体は関数・クラスの実装に使えるものではないため、可変長引数テンプレートの使用は再帰的に行われる。例えば、典型的な例として、C++11におけるprintfの代替の定義例を以下に挙げてみよう:
otherVariable の型はまだ分かりやすい。これは、整数リテラルの型である int となる。
二つ目の方法は、キーワード decltype である。これによって、オペランドで指定した式の型をコンパイル時に取得することができる。
auto で宣言した変数の型はコンパイラにしか分からないので、decltype は auto と組み合わせて使うと特に有用である。
auto はコードの冗長性を省くのにも有用である。例えば、以下のように書かれている場合、
autoを使えばもっと短く書くことができる。なお、vector::cbegin()とvector::cend()は、C++11で追加されたメンバー関数であり、const_iteratorを返すことが規定されている。
コンテナをネストして使うような場合、違いはもっと大きくなる。一方、そのような場合は typedef を使うこともできる。
さらに、標準コンテナの要素とすることも可能である。
同じオブジェクトを参照するポインタの数を得るには、shared_ptrのメンバ関数であるuse_countが使えるだろう。メンバ関数resetは、スマートポインタをリセットする。リセットされたポインタは「空」になり、use_countを呼び出すとゼロを返す。
以下に、shared_ptrの使用例を示す:
これと関連し、弱い参照としてstd::weak_ptrテンプレートも導入される。これもスマートポインタ・参照と同様に振舞うが、shared_ptrとの違いは、参照先の値がポインタによって「所有」されず、弱参照ポインタが存在していても破壊され得る点である。これは、弱参照ポインタには参照先オブジェクトが破壊されてしまうことによる実行時エラーが発生しやすいことを意味している。しかしこれにより、オブジェクトの生存時間に影響しない形で参照を持つことが可能となり、循環参照を防止できる。
このユーティリティは<memory>ヘッダに変更を必要とするが、C++言語拡張は必要としない。
また、std::unique_ptrが前述のauto_ptrの代わりとして導入され、auto_ptrは非推奨とされる。unique_ptrはauto_ptrの全機能を提供するが、左辺値からの暗黙的な移動の際に起こる挙動が異なる。unique_ptrは、C++11のMove Semanticsを用いたコンテナになっている。