扩展命名空间 std
来自 cppreference.cn
目录 |
[编辑] 向 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(); } };
- 对于 float、double 和 long double 以外的任何类型特化模板 std::complex 是未指定的。
- 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++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 120 | C++98 | 用户可以为非用户定义类型显式实例化标准 库模板 |
禁止 |
LWG 232 | C++98 | 用户可以显式特化标准库模板 如果声明依赖于用户定义的外部链接名称(可以引用非用户定义类型) 仅允许用于 |
用户定义类型 用户定义类型 |
LWG 422 | C++98 | 用户可以特化单个成员或成员模板 而无需特化整个标准库类或类模板 |
在这种情况下,行为是 未定义的 |