命名空間
變體
動作

C++ 標準程式庫

出自 cppreference.com
< cpp

C++ 標準程式庫提供了一系列廣泛的功能,可在標準 C++ 中使用。

目錄

[編輯] 類別

A 語言支援程式庫提供了 C++ 語言某些部分所需的元件,例如記憶體配置(new/delete)和例外處理

概念程式庫描述了 C++ 程式可能用於在編譯時期驗證模板引數,並根據型別特性執行函式分派的程式庫元件。

(自 C++20 起)

診斷程式庫提供了一個在 C++ 程式中報告錯誤的一致框架,包括預定義的例外類別

記憶體管理程式庫提供記憶體管理元件,包括智慧型指標範圍分配器(C++11 起)

元編程程式庫描述了用於模板和常數求值期間的功能,包括型別特性整數序列(C++14 起) 以及有理數運算

(C++11 起)

通用工具程式庫包含其他程式庫元素使用的元件,例如用於動態儲存管理的預定義儲存分配器,以及作為 C++ 程式基礎結構使用的元件,例如元組(C++11 起)函式包裝器

容器迭代器範圍(C++20 起)演算法程式庫為 C++ 程式提供了最廣泛使用的演算法和資料結構子集。

字串程式庫支援處理表示為以下型別同質序列的文字:charchar8_t(C++20 起)char16_tchar32_t(C++11 起)wchar_t 以及任何其他類字元型別。

文字處理程式庫提供正規表達式匹配與搜尋(C++11 起)用於文字格式化的工具(C++20 起)識別文字編碼的功能(C++26 起),以及本地化功能

數值程式庫提供數值演算法複數元件,擴展了對數值處理的支援。valarray 元件支援一次處理 n 個元素的運算,在支援此類處理的平台上可能實作為平行運算。亂數元件提供生成偽亂數的功能。(C++11 起)

時間程式庫提供通用的時間工具。

輸入/輸出程式庫提供 iostream 元件,它們是 C++ 程式輸入和輸出的主要機制。它們可以與程式庫的其他元素一起使用,特別是字串、locale 和迭代器。

執行緒支援程式庫提供建立和管理執行緒的元件,包括原子操作互斥以及執行緒間通訊。

(C++11 起)

執行支援程式庫提供一個用於管理通用執行資源上非同步執行的框架。

(C++26 起)

[編輯] 程式庫內容

除非另有指定,C++ 標準程式庫提供C++ 標準程式庫標頭概要中所述的實體巨集的定義。

operator newoperator delete 之外的所有程式庫實體都定義在命名空間 std 或嵌套在命名空間 std 內部的命名空間中(C 標準程式庫設施的實體除外,詳見下文)。在特定命名空間中宣告的名稱是直接在該命名空間中宣告,還是宣告在該命名空間內部的行內命名空間中,這一點未指定。(C++11 起)

[編輯] 標頭

C++ 標準程式庫的每個元素都在一個*標頭*中宣告或定義(視情況而定)。標頭不一定是原始碼檔案,標頭名稱中由 <> 界定的序列也不一定是有效的原始碼檔案名稱。

C++ 標準程式庫提供*C++ 程式庫標頭*和*用於 C 程式庫設施的額外 C++ 標頭*(詳情請參閱「標頭」頁面)。

C++ 程式庫標頭
<algorithm> <iomanip> <list> <ostream> <streambuf>
<bitset> <ios> <locale> <queue> <string>
<complex> <iosfwd> <map> <set> <typeinfo>
<deque> <iostream> <memory> <sstream> <utility>
<exception> <istream> <new> <stack> <valarray>
<fstream> <iterator> <numeric> <stdexcept> <vector>
<functional> <limits>
C++11 中新增的標頭
<array> <condition_variable> <mutex> <scoped_allocator> <type_traits>
<atomic> <forward_list> <random> <system_error> <typeindex>
<chrono> <future> <ratio> <thread> <unordered_map>
<codecvt> <initializer_list> <regex> <tuple> <unordered_set>
C++14 中新增的標頭
<shared_mutex>
C++17 中新增的標頭
<any> <execution> <memory_resource> <string_view> <variant>
<charconv> <filesystem> <optional>
C++20 中新增的標頭
<barrier> <concepts> <latch> <semaphore> <stop_token>
<bit> <coroutine> <numbers> <source_location> <syncstream>
<compare> <format> <ranges> <span> <version>
C++23 中新增的標頭
<expected> <flat_set> <mdspan> <spanstream> <stdfloat>
<flat_map> <generator> <print> <stacktrace>
C++26 中新增的標頭
<contracts> <hazard_pointer> <inplace_vector> <rcu> <text_encoding>
<debugging> <hive> <linalg> <simd>
已移除的標頭
<codecvt> (C++11 起)(在 C++17 中已棄用)(在 C++26 中已移除)
<strstream> (在 C++98 中已棄用)(在 C++26 中已移除)
用於 C 程式庫設施的 C++ 標頭
<cassert> <clocale> <cstdarg> <cstring>
<cctype> <cmath> <cstddef> <ctime>
<cerrno> <csetjmp> <cstdio> <cwchar>
<cfloat> <csignal> <cstdlib> <cwctype>
<climits>
C++11 中新增的標頭
<cfenv> <cinttypes> <cstdint> <cuchar>
已移除的標頭
<ccomplex> (C++11 起)(在 C++17 中已棄用)(在 C++20 中已移除)
<ciso646> (於 C++20 中移除)
<cstdalign> (C++11 起)(在 C++17 中已棄用)(在 C++20 中已移除)
<cstdbool> (C++11 起)(在 C++17 中已棄用)(在 C++20 中已移除)
<ctgmath> (C++11 起)(在 C++17 中已棄用)(在 C++20 中已移除)

獨立實作具有實作定義的標頭集合,請參閱此處以瞭解標頭集合的最小要求。

[編輯] C 標準程式庫

C++ 標準程式庫也提供了 C 標準程式庫的功能,並經過適當調整以確保靜態型別安全。許多程式庫函式的描述都依賴 C 標準程式庫來定義這些函式的語義。

在某些情況下,標準 C++ 中指定的簽章可能與 C 標準程式庫中的簽章不同,並且可能會宣告額外的重載,但行為和前置條件(包括 C 的 restrict 所暗示的那些)(C++17 起) 除非另有說明,否則皆相同。

為了與 C 標準程式庫相容,C++ 標準程式庫提供了下列 C 標頭。這些標頭的預期用途僅限於互通性。C++ 原始碼檔案可能需要包含其中一個標頭才能成為有效的 ISO C。不打算也作為有效的 ISO C 的原始碼檔案不應使用任何 C 標頭。請參閱此處以瞭解說明。

C 標頭
<assert.h> <limits.h> <stdarg.h> <string.h>
<ctype.h> <locale.h> <stddef.h> <time.h>
<errno.h> <math.h> <stdio.h> <wchar.h>
<float.h> <setjmp.h> <stdlib.h> <wctype.h>
<iso646.h> <signal.h>
C++11 中新增的標頭
<complex.h> <inttypes.h> <stdbool.h> <tgmath.h>
<fenv.h> <stdalign.h> <stdint.h> <uchar.h>
C++23 中新增的標頭
<stdatomic.h>
C++26 中新增的標頭
<stdbit.h> <stdchkint.h>

除非另有說明,每個標頭 cxxx 的內容與 C 標準程式庫中指定的對應標頭 xxx.h 的內容相同。然而,在 C++ 標準程式庫中,宣告(C 中定義為巨集的名稱除外)位於命名空間 std 的命名空間範圍內。這些名稱(包括任何新增的重載)是否首先在全域命名空間範圍內宣告,然後透過明確的using 宣告注入到命名空間 std 中,這一點未指定。

在 C 中定義為巨集的名稱(assertoffsetofsetjmpva_argva_endva_start)必須在 C++ 標準程式庫中定義為巨集,即使 C 允許實作為函式。

在 C 中定義為函式的名稱必須在 C++ 標準程式庫中定義為函式。這不允許 C 中允許的,除了函式原型之外還提供一個遮罩巨集的做法。在 C++ 中實現等效的行內行為的唯一方法是將其定義為 extern inline 函式

在 C++ 中是關鍵字或運算子的識別碼不能在 C++ 標準程式庫標頭中定義為巨集。特別是,包含標準標頭 <iso646.h> 沒有任何效果。

[編輯] 與標準 C 中安全函式相關的名稱 (C++17 起)

如果包含任何 C++ 標頭,則以下任何 C 標準 Annex K 名稱是否宣告在全域命名空間中(它們都沒有宣告在命名空間 std 中)是實作定義的。

C 標準 Annex K 名稱
abort_handler_s mbstowcs_s strncat_s vswscanf_s
asctime_s memcpy_s strncpy_s vwprintf_s
bsearch_s memmove_s strtok_s vwscanf_s
constraint_handler_t memset_s swprintf_s wcrtomb_s
ctime_s printf_s swscanf_s wcscat_s
errno_t qsort_s tmpfile_s wcscpy_s
fopen_s RSIZE_MAX TMP_MAX_S wcsncat_s
fprintf_s rsize_t tmpnam_s wcsncpy_s
freopen_s scanf_s vfprintf_s wcsnlen_s
fscanf_s set_constraint_handler_s vfscanf_s wcsrtombs_s
fwprintf_s snprintf_s vfwprintf_s wcstok_s
fwscanf_s snwprintf_s vfwscanf_s wcstombs_s
gets_s sscanf_s vprintf_s wmemcpy_s
gmtime_s mbstowcs_s vscanf_s vswscanf_s
abort_handler_s strcat_s vsnprintf_s wmemmove
ignore_handler_s strcpy_s vsnwprintf_s wprintf_s
localtime_s strerrorlen_s vsprintf_s wscanf_s
L_tmpnam_s strerror_s vsscanf_s
mbsrtowcs_s strlen_s vswprintf_s

[編輯] 使用程式庫

[編輯] 包含標頭

C++ 標準程式庫中的實體定義在標頭中,當翻譯單元包含適當的 #include 預處理器指令時,其內容將對該翻譯單元可用。

翻譯單元可以任意順序包含程式庫標頭。每個標頭可以被包含多次,其效果與只包含一次沒有不同,但包含 <cassert><assert.h> 的效果每次都取決於 NDEBUG 的詞法當前定義。

翻譯單元只能在任何宣告或定義之外,並且在該翻譯單元中首次引用該標頭中宣告的任何實體之前,詞法上包含標頭。不需要診斷。

模組單元中,標頭只能包含在全域模組片段中。

(自 C++20 起)

匯入標頭

C++ 程式庫標頭,或者對於獨立實作而言,由實作提供的這類標頭的子集,統稱為*可匯入的 C++ 程式庫標頭*。

可匯入的 C++ 程式庫標頭的內容,當翻譯單元包含適當的import 宣告時,將可供該翻譯單元使用。

(自 C++20 起)

匯入模組

C++ 標準程式庫提供以下*C++ 程式庫模組*

  • 具名模組 std 匯出由可匯入 C++ 程式庫標頭(例如來自 <bit>std::rotr)和用於 C 程式庫設施的 C++ 標頭(例如來自 <cstdio>std::puts)提供的命名空間 std 中的宣告。它還額外匯出全域命名空間中由 <new> 提供的儲存分配釋放函式的宣告(例如 ::operator new)。
  • 具名模組 std.compat 匯出與具名模組 std 相同的宣告,並且還額外匯出全域命名空間中,對應於由 C++ 標頭為 C 程式庫設施提供的命名空間 std 中的宣告(例如 ::fclose)。

對於標準程式庫中的每個宣告,

  • 它所依附的模組未指定,且
  • 它表示相同的實體,無論是透過包含標頭、匯入標頭單元還是匯入 C++ 程式庫模組而使其可達。
(自 C++23 起)

[編輯] 連結

C++ 標準程式庫中的實體具有儲存期#外部連結。除非另有說明,物件和函式具有預設的 extern "C++" 連結

C 標準程式庫中以外部連結宣告的名稱是具有 extern "C" 連結還是 extern "C++" 連結是實作定義的。C++ 標準建議在這種情況下使用 extern "C++"

程式庫中定義且 C++ 程式所需的物件和函式在程式啟動前會包含在程式中。

[編輯] 標準程式庫實作的要求

[編輯] 保證

C++ 標頭必須提供出現在以下內容中的宣告定義

  • 該標頭的概要中,或
  • 另一個標頭的概要中(該標頭似乎已包含在該標頭的概要中)。

對於在多個標頭中定義的型別和巨集(例如 NULL),無論以何種順序包含任意數量的這些標頭,都不會違反單一定義規則

除非另有指定,C 標準程式庫定義的所有可展開為整數常數表達式類物件巨集都可以在#if 預處理器指令中使用。

呼叫標準程式庫的非成員函式簽章總是導致實際呼叫該函式。因此,符合標準的程式庫實作不能定義可能被有效 C++ 程式呼叫的額外非成員函式。

非成員函式簽章從不宣告額外的預設引數

除非另有指定,標準程式庫中函式對非運算子、非成員函式的呼叫不會使用透過引數依賴名稱查找找到的其他命名空間中的函式。

對於類別(模板)定義中的函式(模板)的每個友元宣告,不為該函式(模板)提供其他宣告。

標準程式庫函式簽章只能在要求為 constexpr 時宣告為 constexpr (libstdc++ cmath 在此處顯著不符合規定)。如果標頭提供了 constexpr 函式或建構函式的任何非定義性宣告,則相應的定義也應在此標頭中提供。

除非另有指定,每個標準程式庫函式都應滿足以下每個要求以防止資料競爭

  • C++ 標準程式庫函式不能(直接或間接)存取當前執行緒之外的其他執行緒可存取的物件,除非這些物件是透過函式的引數(包括 this)直接或間接存取。
  • C++ 標準程式庫函式不能(直接或間接)修改當前執行緒之外的其他執行緒可存取的物件,除非這些物件是透過函式的非 const 引數(包括 this)直接或間接存取。
    • 例如,具有靜態儲存期的物件不能在沒有同步的情況下用於內部目的,因為即使在沒有明確在執行緒之間共享物件的程式中,這樣做也可能導致資料競爭。
  • C++ 標準程式庫函式不能存取透過其引數或透過其容器引數的元素間接可存取的物件,除非是透過呼叫其規範要求在這些容器元素上執行的函式。
  • 對透過呼叫標準程式庫容器或字串成員函式獲得的迭代器進行的操作可以存取,但不能修改底層容器。
    • 特別是,使迭代器失效的容器操作與對與該容器相關聯的迭代器進行的操作會發生衝突。
  • C++ 標準程式庫函式只能在當前執行緒內執行所有操作,如果這些操作具有對使用者可見的效果。
    • 沒有可見副作用的操作可以平行化。
(C++11 起)

對於 C++ 標準程式庫中定義的,要求從 C++ 標準程式庫中定義的另一個類別派生的每個類別,

  • 如果基底類別被指定為 virtual,則它必須是虛擬的,
  • 如果基底類別未被指定為 virtual,則它不能是虛擬的,且
  • 除非另有指定,具有不同名稱的型別應為不同型別。

除非另有指定,C++ 標準程式庫中指定的所有型別都是非最終型別。

(C++11 起)

如果 C++ 標準程式庫中定義的函式被指定在特定情況下拋出給定型別的例外,則拋出的例外只能是該型別或從該型別派生的型別,以便基底型別的例外處理程式可以捕獲它。

C 標準程式庫中的函式只能在該函式呼叫了由程式提供的、會拋出例外的函式時拋出例外(qsort()bsearch() 符合此條件)。

C++ 標準程式庫中定義的解構函式操作從不拋出例外。C++ 標準程式庫中的每個解構函式都表現得好像它具有不拋出例外規範

如果 C++ 標準程式庫中的函式透過 std::error_code 物件報告錯誤,則該物件的 category() 成員對於源自作業系統的錯誤必須返回 std::system_category(),或者對於源自其他地方的錯誤,返回實作定義的 std::error_category 物件的引用。每個這些錯誤類別的 value() 可能值應定義。

C++ 標準程式庫中定義的型別物件可以被移動。移動操作可以明確指定或隱式生成。除非另有指定,此類被移動的物件將處於有效但未指定的狀態。

C++ 標準程式庫中定義的型別物件可以移動指派給自身。除非另有指定,此類指派會將物件置於有效但未指定的狀態。

(C++11 起)

[編輯] 實作自由

C++ 標準程式庫中的任何成員或非成員函式是否定義為行內函式,這一點未指定。

對於非虛擬的 C++ 標準程式庫成員函式,可以宣告一組不同的成員函式簽章,前提是任何對該成員函式的呼叫,如果會從給定宣告集中選擇一個重載,其行為應如同選擇了該重載。這允許,例如:

  • 新增帶有預設引數的參數,
  • 用兩個或多個具有等效行為的成員函式替換帶有預設引數的成員函式,或
  • 為成員函式名稱新增額外的簽章。

除非另有指定,C++ 標準程式庫中哪些函式可以遞迴重入是實作定義的。

C++ 標準程式庫實作可以在執行緒之間共享其內部物件,如果這些物件對使用者不可見且受到資料競爭的保護。

(C++11 起)

C++ 標準程式庫中的任何函式簽章或類別是否是 C++ 標準程式庫中另一個類別的友元,這一點未指定。

此處描述的名稱和全域函式簽章保留給實作。

C++ 標準程式庫中的任何類別都可以從名稱保留給實作的類別派生。如果 C++ 標準程式庫中定義的類別需要從 C++ 標準程式庫中的其他類別派生,則該類別可以直接從所需的基底類別派生,或透過名稱保留給實作的基底類別層次結構間接派生。

如果 C++ 標準程式庫中定義的函式未指定拋出例外,但也沒有不拋出例外規範,則拋出的例外是實作定義的,但其型別應為 std::exception 或任何從 std::exception 派生的型別。

非虛擬函式的例外規範可以透過新增不拋出例外規範來強化。

[編輯] 附註

功能測試巨集 數值 標準 功能
__cpp_lib_modules 202207L (C++23) 標準程式庫模組 stdstd.compat

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯應用於之前的 C++ 標準。

DR 應用於 出版時的行為 正確的行為
LWG 1 C++98 來自
C 標準程式庫的名稱的語言連結未指定
它們是
實作定義的
LWG 119 C++98 虛擬函式的例外規範
可以被強化
僅允許用於
非虛擬函式
LWG 147 C++98 非成員函式的規範
只考慮全域函式
也考慮
非全域函式
LWG 225 C++98 標準程式庫函式可能會呼叫非成員函式
由於引數依賴查找,來自其他命名空間的函式
禁止,除非
另有指定
LWG 336 C++98 <strstream> 不是 C++ 程式庫標頭 它是一個 C++ 程式庫標頭
LWG 343 C++98 程式庫標頭依賴關係未指定 已指定(列在概要中)
LWG 456 C++98 用於 C 程式庫設施的 C++ 標頭可能
僅在命名空間 std 中提供定義
允許在全域命名空間中定義
然後注入到命名空間 std
LWG 465 C++98 在 C++ 中是關鍵字或運算子的識別碼可能
在 C++ 標準程式庫標頭中定義為巨集
(只有 <ciso646> 要求不將它們定義為巨集)
所有 C++ 標準
程式庫標頭不能
將它們定義為巨集
LWG 1178 C++98 C++ 標頭必須包含一個 C++ 標頭
包含任何所需定義的標頭
C++ 標頭必須提供宣告
和定義,它們直接或
間接包含在其概要中
LWG 2013 C++11 未指定函式是否不
標準要求為 constexpr 的函式可以
由標準程式庫宣告為 constexpr
禁止
LWG 2225 C++98 如果標頭
包含在不正確的位置,則需要診斷
不需要診斷
在這種情況下

English Deutsch 日本語 中文(简体) 中文(繁體)