C++11
正規表現のために作られた、多くの非標準あるいは準標準のライブラリがある。このようなアルゴリズムを使うのは非常に一般的なので、オブジェクト指向言語の能力を用いて、標準ライブラリにもこの機能が導入される。<regex>で提供される正規表現はECMAScriptとの互換性がある。POSIXなどの正規表現もサポートする。ただし、Perlの正規表現はサポートされないため、Perl正規表現を使いたければBoost C++ライブラリのBoost.RegexかBoost.XPressiveを使うことになる。
新ライブラリでは、新ヘッダ<regex>が定義され、2つの新クラスが導入される:
正規表現を表すクラステンプレートbasic_regex
結果を表すクラステンプレートmatch_results
検索のためにregex_search関数が使われ、「検索と置換」とためにregex_replace関数が使われ、新たな文字列を返す。アルゴリズムregex_searchとregex_replaceは正規表現と文字列を取り、結果をmatch_resultsに収める。
以下にmatch_resultsの使用例を示す:
注意: C++の文字列リテラルではバックスラッシュはエスケープ文字として扱われるため、例ではバックスラッシュを二つ重ねている。C++11のraw文字列機能により、この問題は回避できる。
regexライブラリ自体は、既存のヘッダの変更や言語拡張を必要としない。
C++規格には、一引数コンストラクタを暗黙的な型変換関数として扱われないようにするための修飾子として、explicitキーワードが導入された。しかし、これは変換関数には何の効果も無い。
例えば、スマートポインタのクラスは、本物のポインタと同じように振る舞うためにoperator bool()を持っていることがある。この変換を追加することで、if (smart_ptr_variable)としてそれをテストできる(ポインタが非NULLならtrueを、NULLならfalseと判定できるはずである)。しかし、この変換を認めると、不本意な変換も発生してしまう。C++のboolは算術型として定義されているため、整数型やさらには浮動小数点型としてまで変換されてしまい、ユーザーが意図しない数値型としての動作を引き起こしてしまうのである。
C++11では、explicitキーワードを変換関数にも適用できるようになる。コンストラクタへの適用と組み合わせ、さらなる暗黙的型変換を防止できる。
random_deviceクラスを用いて、unsigned int型の非決定的乱数を生成できる。実装には、システムから独立した入力を持つデバイス(例えば、非同期的な外部カウンタや、特殊なトランスデューサーなど)の使用や、伝統的な「結果を調節する」擬似乱数エンジンの使用が必要である。libstdc++やlibc++では、/dev/urandomを読み出す実装となっている。
動的メモリ確保は、プログラミング言語の歴史においても昔からの論点である。C/C++では動的に確保したメモリに対する明示的な解放が必要だが、Javaなどに代表される多くの現代的プログラミング言語は、ガベージコレクションによる自動メモリ管理の仕組みを備えている。
C++のポインタには、多くの興味深い性質がある:
コピーできる。
代入できる。
void *を総称的ポインタとして使える。
静的キャストで、基底クラスのポインタに変換できる。
動的キャストで、派生クラスのポインタに変換できる。
一方、C++のポインタには主に以下のような欠点や危険な性質がある:
動的に割り当てられたメモリを手動管理する責任がプログラマ側にある。
メモリ上の、不正なアドレスや未割り当てのアドレスが参照できる。
この問題を解消・軽減するためのイディオムとして、RAIIに基づいたスマートポインタがよく利用される。スマートポインタは、通常のポインタの利点を維持したまま、弱点を大幅に削ったものである。C++03までの標準C++ライブラリにもスマートポインタの一種としてstd::auto_ptrが存在したが、制約が多く、決して使いやすいとは言えなかった。C++11では、Boost C++ライブラリをベースとした、いくつかの新しいスマートポインタが標準化された。
クラステンプレートstd::shared_ptrは、同じオブジェクトに対する「同等の」参照をカウントする機能(参照カウント)を持ち、関連するスマートポインタ間でオブジェクトの所有権を共有する。
C++標準ライブラリへのハッシュテーブル(順序付けの無い連想コンテナ)の導入要求は、最も繰り返されてきた要求の1つである。これは、時間的な制約のみのために、現在の標準(1995年、1998年)に導入されなかった。ハッシュテーブルは最悪の場合(大量の衝突が発生)の効率は平衡木に劣るが、現実のアプリケーションでは多くの場合効率的である。
衝突の管理は、チェイン法によってのみ行われる。これは、委員会には、多くの実装上の問題(特に要素の消去が認められるような場合)があるオープンアドレス法を標準化する機会がないからである。非標準のライブラリの持つ、独自のハッシュテーブル実装と名前が衝突しないように、"hash"の代わりに"unordered"を使用している。
ハッシュテーブルには4種類あり、同じキーを持つ要素を認めるかどうかと、キーに値を関連付けるかどうかで区別される。
新クラスは、コンテナクラスの要件を全て満たし、要素へのアクセスに必要な全てのメソッドを備える:insert, erase, begin, end.
この新ユーティリティは、C++言語の拡張は必要ない。<functional>ヘッダへの小さな拡張と、<unordered_set>ヘッダ、<unordered_map>ヘッダの導入を行うのみである。他の標準クラスには変更の必要がなく、標準ライブラリの他の拡張にも依存しない。
コンピュータは決定的な振る舞いをするものであるが、疑似乱数による乱数列を生成することにより、(外見だけでも)非決定的な振る舞いが必要となるようなアプリケーションがある。
標準に用意されている方法は、rand関数のみである。しかし、十分な定義がされていないため、そのアルゴリズムは完全にライブラリ開発者に任せられている。新たな乱数生成ユーティリティは<random>ヘッダを通して定義される。他のヘッダやC++言語への修正は必要としない。
乱数生成器は、内部状態と、結果を計算し次の状態を生成するための関数をもつ。この2つの特性によって、乱数生成エンジンが定まる。他の特性として、生成結果や乱数の間隔や密度の分布も重要である。
他の多くの言語と同様、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形式にも拡張される。文字列リテラルが例外なのは、文字列には、文字列の型と特別な意味の指定を行う接頭辞があるからである。
標準Cの関数宣言の構文は、C言語の機能に対しては最適なものであった。C++ は C から離れて発展してきたが、その基本的な構文を維持しつつ、必要に応じて拡張してきた。しかし、C++ がさらに複雑になってくると、多数の制約、特に関数テンプレートの宣言に関する制約が露呈するようになった。例えば、次のように関数の戻り値の型が文脈によって決まる場合、C++03では明示的にテンプレート型引数で指定するか、boost::result_ofやboost::decayのような型推論をエミュレートする補助ライブラリに頼るしかなかった。
TResult 型は、LHS と RHS の型を加算して作られる型であり、それらの実際の型によって決まる。
C++11では、前述のように decltype という機能が追加されたが、これを直接戻り値の型推論に使うことはできない。
パーサーが decltype(lhs+rhs) を解析する時点で、lhs と rhs はまだ定義されておらず、有効な識別子にはなっていない。したがって、この書き方も C++ に適合していない。
この問題に対処するために、C++11 では次のような関数の定義と宣言の構文が導入された。
autoでいったん型を前置しておき、後置のdecltypeで補足している。
この構文は、非テンプレート関数の宣言や定義にも使用できる。
この構文で使われるautoキーワードは、自動型推論の場合とは異なった意味をもつ。
これにより、SequenceClass は、整数の列から構築できるようになる。
このコンストラクタは、初期化子リストコンストラクタと呼ばれる特殊なコンストラクタである。このコンストラクタを持つクラスは、統一的な初期化構文の適用の際に特別に扱われる(後述)。
std::initializer_list<> クラスは、C++11 標準ライブラリのファーストクラスの型である。しかし、これを構築できるのは、{ } 構文を用いてコンパイラが静的に構築する場合だけである。一度構築されたらその後コピーはできず参照渡しするしかない。初期化リストは定数であり、一度構築されたらそのメンバを変更することはできず、メンバ中のデータも変更できない。
std::initializer_list は実際の型であるため、クラスコンストラクタのみならずそれ以外の場所でも使用できる。例えば、一般の関数の引数とすることもできる。
テンプレートを用いた総称プログラミングを導入するのに、新形式の括弧を導入するのが必要であった。そのためC++には、丸括弧"()"、角括弧"[]"、波括弧"{}"に加えて、山括弧"<>"が導入された。しかし、これにより字句的曖昧さが生じ、(プログラマの意図とは違う、という意味で)間違って解析され、構文エラーになるという事態が発生した:
C++11の字句解析では、最も深くネストした開き括弧が山括弧"<"である場合、">"は、次に">"や"="が続いていても山閉じ括弧として扱われる。これにより、上記のエラーは最後のものを除いて修正される。最後のものを修正するには、曖昧さを取り除くために丸括弧を足さなくてはならない。
こうすることで、"("から")"の間については、コンパイラは<>の文字を山括弧と扱わなくなる。