C++11
C++03では、オブジェクトにコンストラクタ、コピーコンストラクタ、代入演算子 (operator=)、そしてデストラクタが与えられていない場合、コンパイラが自動的にそれらを提供する。ユーザーは自身のバージョンを定義することで、デフォルトの動作を上書きできる。また、C++は全てのクラスに適用されるグローバルな演算子(operator=やoperator new)も提供しており、その動作もユーザーが上書きできる。
しかし、デフォルトで作られる関数の生成を制御する方法が非常に少ないという問題がある。例えば、クラスを実質的にコピー不能にするには、コピーコンストラクタと代入演算子をprivateとして宣言し、定義しないことによって実現できる。これらの関数を使用しようとすると、コンパイラやリンカがエラーを報告するようになるというわけである。しかし、これは理想的な解法とはいえないであろう。
さらに言えば、例えばデフォルトコンストラクタなど、コンパイラに対して明示的に生成するよう伝えておくことも有用である。オブジェクトに「どんなものであれ一つでも」コンストラクタが定義されているのであれば、コンパイラはデフォルトコンストラクタを生成しない。
大量の新機能が、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に搭載されることが予定されているものである。
enum classの内部的な型はコンパイラの実装に依存しない。デフォルトではintであり、次のように明示的に指定することもできる。
列挙名は列挙型のスコープで定義される。列挙名を使うときには、Enum2::Val1のように明示的にスコープを指定しなければならない。上の例では、Val1は未定義である。
さらに、C++11では従来スタイルの列挙型にも、明示的なスコープや内部的な型の指定ができる。
この場合、列挙名は列挙型のスコープで定義される(Enum3::Val1)が、後方互換性のため、列挙型が定義されたスコープにも定義される(Val1)。
C++11では列挙型の前方宣言も可能である。以前は列挙型のサイズが内容によって決まっていたため、列挙型は前方宣言できなかった。明示的あるいは暗黙的に列挙のサイズが決定できさえすれば、前方宣言が可能である。
以下の機能は、従来のC++では全く不可能であったり、異常に冗長な記述が必要だったり、可搬性の無いライブラリを使わないといけなかったりしたような機能を提供するものである。
テンプレート関数オブジェクトの戻り値の型を(コンパイル時に)決定するのに、直感的な方法がない。特に引数の型に基づいて決まる場合は顕著である。
例として以下のコードを挙げる:
calculusクラステンプレートをclearクラスで実体化する場合(calculus<clear>として実体化する場合)、calculus関数オブジェクトはclear関数オブジェクトと同じ戻り値型を持つ。
ここで、calculusクラステンプレートをconfusedクラスで実体化する場合(calculus<confused>として実体化する場合)を考えよう:
calculusの戻り値型はconfusedクラスと同じではない(calculus<confused>.operator()の実体化に伴い、intから doubleへの変換や逆変換が起こる)。
次期標準に提案されている新ライブラリで、result_ofクラステンプレートが導入され、各宣言ごとに関数オブジェクトの戻り値型の決定と使用が可能になる。これを用いて、関数オブジェクトの戻り値型を取得するようにすることでcalculusを修正した:
このようにすることで、関数オブジェクトcalculus_ver2<confused>の実体化の際に、型変換は発生しない。
関数オブジェクト呼び出し時の戻り値型の決定は、式の戻り値型を決定するという一般的な問題の一部である。将来的には、問題の起き得る箇所にdecltypeのような機能を使うことで解決されるだろう。
C++ コア言語の特筆すべき改良点には、マルチスレッドのサポートや、ジェネリックプログラミングのサポート、一様な初期化構文やパフォーマンス向上等が挙げられる。
このページでは、コア言語の機能拡張や変更点を、実行時パフォーマンス向上、ビルド時パフォーマンス向上、使いやすさの向上、全く新しい機能の4つに分けて説明する。機能によっては複数の項目に該当するが、最もよく当てはまる項目で述べることとする。
型が明らかな場合、次のように書くこともできる。
統一的な初期化構文は、必ずしもコンストラクタ構文の代用となるものではない。コンストラクタ構文が必要な場合もある。クラスが初期化子リストコンストラクタ (TypeName(std::initializer_list<SomeType>)) を持つような場合、(初期化子リストがシーケンスコンストラクタの型に適合するのならば)初期化子リストコンストラクタが優先して適用される。例えば、C++11 の std::vector は、そのテンプレート型の初期化子リストコンストラクタを持つ。つまり、
のように書いた場合、初期化子リストコンストラクタが呼ばれる。固定長の std::vector を生成するための、サイズを指定する引数ひとつを取るコンストラクタstd::vector(size_type n)を呼ぶためには、標準のコンストラクタ構文を使う必要がある。
C++03やCでは、変数の型は使用に際して明示的に指定しなければならない。しかし、テンプレート型やテンプレートメタプログラミングなどにおいては、特に関数の戻り値型が複雑に定義されているような場合、型を簡単に書き下せないことがある。そのような場合には、中間結果を変数に格納することが難しく、メタプログラミングライブラリの内部仕様を知っていなくてはならなくなる場合もある。
C++11 では型推論により、この制約を軽減する方法が二つ提供された。一つ目の方法は、明示的に初期化される変数の定義に auto キーワードを使う方法である。これにより、初期化子によって変数の型が特定される。
someStrangeCallableType の型は、関数テンプレート boost::bind がその引数に応じて返す戻り値の型である。これはコンパイラにとっては容易に判別できるが、ユーザーが調べるのは困難である。