擴充套件名稱空間 std
來自 cppreference.com
目錄 |
[編輯] 向 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
新增任何標準庫類模板的模板特化。
// 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 特化為除 float、double 和 long double 以外的任何型別是未指定的。
- std::numeric_limits 的特化必須以可作為整型常量表達式使用的方式定義主模板中宣告為static const(C++11 前)static constexpr(C++11 起)的所有成員。
|
(C++11 起) |
(C++17 前) |
宣告標準庫類或類模板的任何成員類模板的完整或部分特化是未定義行為。
本節不完整 原因:微型示例 |
[編輯] 函式模板和模板的成員函式
只有當宣告依賴於至少一個程式定義型別且特化滿足原始模板的所有要求(除非此類特化被禁止)時,才允許向名稱空間 |
(C++20 前) |
宣告任何標準庫函式模板的完整特化是未定義行為。 |
(C++20 起) |
本節不完整 原因:微型示例 |
宣告標準庫類模板的任何成員函式的完整特化是未定義行為。
本節不完整 原因:微型示例 |
宣告標準庫類或類模板的任何成員函式模板的完整特化是未定義行為。
本節不完整 原因:微型示例 |
[編輯] 變數模板
宣告任何標準庫變數模板的完整或部分特化是未定義行為,除非明確允許。
|
(C++14 起) |
[編輯] 模板的顯式例項化
只有當宣告依賴於至少一個程式定義型別的名稱且例項化滿足原始模板的標準庫要求時,才允許顯式例項化標準庫中定義的類(C++20 起)模板。
本節不完整 原因:微型示例 |
[編輯] 其他限制
名稱空間 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++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 120 | C++98 | 使用者可以為非使用者定義型別顯式例項化標準 庫模板 |
已禁止 |
LWG 232 | C++98 | 如果宣告依賴於具有外部連結的使用者定義名稱(可以引用非使用者定義型別),則使用者可以顯式特化標準庫模板。 如果宣告依賴於具有外部連結的使用者定義名稱(可以引用非使用者定義型別),則使用者可以顯式特化標準庫模板。 如果宣告依賴於具有外部連結的使用者定義名稱(可以引用非使用者定義型別),則使用者可以顯式特化標準庫模板。 |
僅允許用於 使用者定義型別 |
LWG 422 | C++98 | 使用者可以特化單個成員或成員模板 而無需特化整個標準庫類或類模板 |
在這種情況下,行為是 未定義的 |