名稱空間
變體
操作

擴充套件名稱空間 std

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 

目錄

[編輯] std 新增宣告

向名稱空間 stdstd 內的任何巢狀名稱空間新增宣告或定義是未定義行為,但以下列出的少數例外情況除外。

#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 特化為除 floatdoublelong double 以外的任何型別是未指定的。
  • std::hash 為程式定義型別所做的特化必須滿足 Hash 要求。
  • std::atomic 的特化必須具有已刪除的複製建構函式、已刪除的複製賦值運算子和 constexpr 值建構函式。
  • std::istreambuf_iterator 的特化必須具有平凡的複製建構函式、constexpr 預設建構函式和平凡的解構函式。
(C++11 起)
(C++17 前)

宣告標準庫類或類模板的任何成員類模板的完整或部分特化是未定義行為。

[編輯] 函式模板和模板的成員函式

只有當宣告依賴於至少一個程式定義型別且特化滿足原始模板的所有要求(除非此類特化被禁止)時,才允許向名稱空間 std 新增任何標準庫函式模板的模板特化。

(C++20 前)

宣告任何標準庫函式模板的完整特化是未定義行為。

(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 使用者可以特化單個成員或成員模板
而無需特化整個標準庫類或類模板
在這種情況下,行為是
未定義的