名前空間
変種
操作

std名前空間の拡張

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 

目次

[編集] stdへの宣言の追加

std名前空間またはstdにネストされた名前空間に宣言または定義を追加することは、以下に記すいくつかの例外を除き、未定義の動作です。

#include <utility>
 
namespace std
{
    // a function definition added to namespace std: undefined behavior
    pair<int, int> operator+(pair<int, int> a, pair<int, int> b)
    {
        return {a.first + b.first, a.second + b.second};
    }
}

[編集] テンプレート特殊化の追加

[編集] クラステンプレート

標準ライブラリのクラステンプレートのテンプレート特殊化をstd名前空間に追加することは、その宣言が少なくとも1つのプログラム定義型に依存し、かつ特殊化が元のテンプレートのすべての要件を満たす場合にのみ許可されます。ただし、そのような特殊化が禁止されている場合は除きます。

// Get the declaration of the primary std::hash template.
// We are not permitted to declare it ourselves.
// <typeindex> is guaranteed to provide such a declaration, 
// and is much cheaper to include than <functional>.
 
#include <typeindex> 
 
// Specialize std::hash so that MyType can be used as a key in 
// std::unordered_set and std::unordered_map.  Opening namespace
// std can accidentally introduce undefined behavior, and is not
// necessary for specializing class templates.
template<>
struct std::hash<MyType>
{
    std::size_t operator()(const MyType& t) const { return t.hash(); }
};
  • std::complexテンプレートをfloatdouble、およびlong double以外の型に対して特殊化することは未規定です。
  • 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名前空間に追加することは、その宣言が少なくとも1つのプログラム定義型に依存し、かつ特殊化が元のテンプレートのすべての要件を満たす場合にのみ許可されます。ただし、そのような特殊化が禁止されている場合は除きます。

(C++20まで)

標準ライブラリの関数テンプレートの完全特殊化を宣言することは、未定義の動作です。

(C++20以降)

標準ライブラリのクラステンプレートのメンバ関数の完全特殊化を宣言することは、未定義の動作です。

標準ライブラリのクラスまたはクラステンプレートのメンバ関数テンプレートの完全特殊化を宣言することは、未定義の動作です。

[編集] 変数テンプレート

標準ライブラリの変数テンプレートの完全または部分特殊化を宣言することは、明示的に許可されている場合を除き、未定義の動作です。

(C++20以降)
(C++14以降)

[編集] テンプレートの明示的インスタンス化

標準ライブラリで定義されたクラス(C++20以降)テンプレートの明示的インスタンス化は、その宣言が少なくとも1つのプログラム定義型の名前に依存し、かつインスタンス化が元のテンプレートの標準ライブラリ要件を満たす場合にのみ許可されます。

[編集] その他の制限

std名前空間は、インライン名前空間として宣言することはできません。

アドレス指定可能な関数に関する制限

標準ライブラリ関数または標準ライブラリ関数テンプレートのインスタンス化へのポインタ、参照(フリー関数および静的メンバ関数用)、またはポインタ・ツー・メンバ(非静的メンバ関数用)を形成しようとするC++プログラムの動作は、それがアドレス指定可能な関数(下記参照)として指定されていない限り、未規定(おそらく形式エラー)です。

C++17では正常に定義されていた以下のコードは、C++20以降、未規定の動作となり、コンパイルに失敗する可能性があります。

#include <cmath>
#include <memory>
 
int main()
{
    // by unary operator&
    auto fptr0 = &static_cast<float(&)(float, float)>(std::betaf);
 
    // by std::addressof
    auto fptr1 = std::addressof(static_cast<float(&)(float, float)>(std::betaf));
 
    // by function-to-pointer implicit conversion
    auto fptr2 = static_cast<float(&)(float)>(std::riemann_zetaf);
 
    // forming a reference
    auto& fref = static_cast<float(&)(float)>(std::riemann_zetaf);
}

指定されたアドレス指定可能な関数

(C++20以降)

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 120 C++98 ユーザーは標準
ライブラリテンプレートをユーザー定義型ではない型に対して明示的にインスタンス化できました。
禁止された
LWG 232 C++98 ユーザーは標準ライブラリテンプレートを特殊化できました。
宣言が外部リンケージを持つユーザー定義名に依存する場合(ユーザー定義型ではない型を参照できる)
ユーザー定義型に対してのみ許可
ユーザー定義型のみ
ユーザー定義型
LWG 422 C++98 ユーザーは、標準ライブラリクラスまたはクラステンプレート全体を特殊化することなく、個々のメンバまたはメンバテンプレートを特殊化できました。
標準ライブラリクラスまたはクラステンプレート全体の特殊化なしに、個々のメンバまたはメンバテンプレートを特殊化できました。
この場合の動作は
未定義となる
English 日本語 中文(简体) 中文(繁體)