名前空間 std
の拡張
目次 |
[編集]std
への宣言の追加
下に記載している少数の例外を除いて、名前空間 std
または std
内のネストした名前空間に宣言または定義を追加することは未定義動作です。
#include <utility>namespace std {// 名前空間 std に追加された関数定義 (未定義動作)。 pair<int, int> operator+(pair<int, int> a, pair<int, int> b){return{a.first+b.first, a.second+b.second};}}
[編集]テンプレートの特殊化の追加
そのような特殊化が禁止されている場合を除き、その宣言が少なくとも1つのプログラム定義された型に依存していて、その特殊化が元のテンプレートに対するすべての要件を満たしている場合に限り、標準ライブラリのクラス(C++20以上)テンプレートに対するテンプレート特殊化を名前空間 std
に追加することが許されています。
// std::hash のプライマリテンプレートの宣言をインクルードします// (それを自分で宣言することは許されていません)。// <typeindex> はそのような宣言を提供することが保証されており、// <functional> をインクルードするよりも軽量です。#include <typeindex> // MyType を std::unordered_set や std::unordered_map で// キーとして使用できるように、 std::hash を特殊化します。// クラステンプレートを特殊化するために namespace std { ... } を// 開く必要はありません。template<>structstd::hash<MyType>{std::size_t operator()(const MyType& t)const{return t.hash();}};
- 標準ライブラリのクラステンプレートのいずれかのメンバ関数の完全特殊化を宣言することは未定義動作です。
This section is incomplete Reason: mini-example |
- 標準ライブラリのクラスまたはクラステンプレートのいずれかのメンバ関数テンプレートの完全特殊化を宣言することは未定義動作です。
This section is incomplete Reason: mini-example |
- 標準ライブラリのクラスまたはクラステンプレートのいずれかのメンバクラステンプレートの完全または部分特殊化を宣言することは未定義動作です。
This section is incomplete Reason: mini-example |
| (C++14以上) |
- float、 double、および long double 以外の何らかの型に対するテンプレート std::complex の特殊化は未規定です。
- std::numeric_limits の特殊化は、そのプライマリテンプレートの
static const
(C++11未満)static constexpr
(C++11以上) 宣言されているすべてのメンバを、整数定数式として使用可能な方法で、定義しなければなりません。
| (C++11以上) |
| (C++17未満) |
| (C++20以上) |
[編集]テンプレートの明示的実体化
その宣言が少なくとも1つのプログラム定義された型に依存していて、その実体化が標準ライブラリの元のテンプレートに対する要件を満たす場合に限り、標準ライブラリで定義されているクラス(C++20以上)テンプレートを明示的実体化することが許されています。
This section is incomplete Reason: mini-example |
[編集]その他の制限
名前空間 std
は inline
名前空間として宣言してはなりません。
[編集]アドレス可能な関数
C++ プログラムが標準ライブラリ関数または標準ライブラリ関数テンプレートの実体化へのポインタ、参照 (自由関数および静的メンバ関数の場合)、またはメンバポインタ (非静的メンバ関数の場合) の形成を明示的または暗黙に試みる場合、それがアドレス可能な関数であると明示されていない限り、その動作は未規定です (ill-formed になることもあります)。 標準ライブラリ内のアドレス可能な関数は、唯一の引数としてストリームへの参照を取る関数 (または関数テンプレートの実体化) である入出力マニピュレータ (std::endl や std::boolalpha など) だけです。 以下のコードは C++17 では well-defined でしたが、 C++20 からは未規定の動作の原因となり、コンパイルに失敗する可能性もあります。 #include <cmath>#include <memory>int main(){auto fptr0 =&std::betaf;// 単項演算子 & によって。auto fptr1 =std::addressof(std::betal)// std::addressof によって。auto fptr2 =std::riemann_zetaf;// 関数からポインタへの暗黙の変換によって。auto&fref =std::riemann_zetal;// 参照の形成。} | (C++20以上) |