名前空間
変種
操作

名前空間 std の拡張

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (C++20未満)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 

目次

[編集] 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 <> struct hash<MyType> {
      std::size_t operator()(const MyType& t) const { return t.hash(); }
    };
}
  • 標準ライブラリのクラステンプレートのいずれかのメンバ関数の完全特殊化を宣言することは未定義動作です。
  • 標準ライブラリのクラスまたはクラステンプレートのいずれかのメンバ関数テンプレートの完全特殊化を宣言することは未定義動作です。
  • 標準ライブラリのクラスまたはクラステンプレートのいずれかのメンバクラステンプレートの完全または部分特殊化を宣言することは未定義動作です。
  • 明示的に許されている場合を除いて、標準ライブラリのいずれかの変数テンプレートの完全または部分特殊化を宣言することは未定義動作です。
(C++14以上)
  • float、 double、および long double 以外の何らかの型に対するテンプレート std::complex の特殊化は未規定です。
  • std::numeric_limits の特殊化は、そのプライマリテンプレートの static const (C++11未満)static constexpr (C++11以上) 宣言されているすべてのメンバを、整数定数式として使用可能な方法で、定義しなければなりません。
  • プログラム定義された型に対する std::hash の特殊化は Hash の要件を満たさなければなりません。
  • std::atomic の特殊化は削除されたコピーコンストラクタ、削除されたコピー代入演算子、および constexpr 値コンストラクタを持たなければなりません。
  • std::istreambuf_iterator の特殊化はトリビアルなコピーコンストラクタ、 constexpr デフォルトコンストラクタ、およびトリビアルなデストラクタを持たなければなりません。
(C++11以上)
(C++17未満)
  • std::disable_sized_sentinelstd::ranges::disable_sized_range および std::ranges::enable_view の特殊化は定数式で使用可能でなければならず、 const bool 型でなければなりません。 さらに、
    • std::disable_sized_sentinel は cv 修飾されていない非配列オブジェクト型 S および I (少なくともひとつはプログラム定義された型でなければなりません) に対して特殊化しても構いません。
    • std::ranges::disable_sized_range および std::ranges::enable_view は cv 修飾されていないプログラム定義された型に対して特殊化しても構いません。
(C++20以上)

[編集] テンプレートの明示的実体化

その宣言が少なくとも1つのプログラム定義された型に依存していて、その実体化が標準ライブラリの元のテンプレートに対する要件を満たす場合に限り、標準ライブラリで定義されているクラス (C++20以上)テンプレートを明示的実体化することが許されています。

[編集] その他の制限

名前空間 stdinline 名前空間として宣言してはなりません。

[編集] アドレス可能な関数

C++ プログラムが標準ライブラリ関数または標準ライブラリ関数テンプレートの実体化へのポインタ、参照 (自由関数および静的メンバ関数の場合)、またはメンバポインタ (非静的メンバ関数の場合) の形成を明示的または暗黙に試みる場合、それがアドレス可能な関数であると明示されていない限り、その動作は未規定です (ill-formed になることもあります)。

標準ライブラリ内のアドレス可能な関数は、唯一の引数としてストリームへの参照を取る関数 (または関数テンプレートの実体化) である入出力マニピュレータ (std::endlstd::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; // 参照の形成。
    auto mfptr = &std::allocator<int>::allocate; // メンバ関数ポインタの形成。
}
(C++20以上)