命名空間
變體
動作

反射的擴充功能

出自 cppreference.com
 
 
實驗性
技術規範
檔案系統函式庫 (filesystem TS)
函式庫基礎 (library fundamentals TS)
函式庫基礎 2 (library fundamentals TS v2)
函式庫基礎 3 (library fundamentals TS v3)
平行化擴充 (parallelism TS)
平行化擴充 2 (parallelism TS v2)
並行化擴充 (concurrency TS)
並行化擴充 2 (concurrency TS v2)
概念 (concepts TS)
範圍 (ranges TS)
反射 (反射技術規範)
數學特殊函數 (special functions TR)
實驗性非 TS
模式匹配
線性代數
std::execution
合約
2D 圖形
 
反射的擴充功能
概念
後設物件操作
變數
函式參數
可呼叫 (Callable)
VariableCallable
NamespaceCallable
括號表達式
函式呼叫表達式
函式樣式轉換
VariableFunction
 

C++ 反射擴充功能,ISO/IEC TS 23619:2021,指定了對核心語言的修改,並定義了本頁列出的 C++ 標準函式庫新元件。

反射技術規範 (Reflection TS) 基於 C++20 標準(除了概念的定義是按照概念技術規範 (Concepts TS) 的風格指定)。

目錄

[編輯] 核心語言變更

[編輯] reflexpr 指定符

一個 reflexpr-指定符 的形式為 reflexpr ( reflexpr-運算元 ),並指定一個後設物件類型(見下文)。

reflexpr-運算元 可以是以下之一

:: (1)
類型識別碼 (2)
巢狀名稱指定符(可選) 命名空間名稱 (3)
識別碼表達式 (4)
( 表達式 ) (5)
函式呼叫表達式 (6)
函式樣式類型轉換表達式 (7)

其中 函式呼叫表達式

後置表達式 ( 表達式清單(可選) )

函式樣式類型轉換表達式 是以下執行 顯式型別轉換 的表達式類型

簡單類型指定符 ( 表達式清單(可選) ) (1)
類型名稱指定符 ( 表達式清單(可選) ) (2)
簡單類型指定符 大括號初始器清單 (3)
類型名稱指定符 大括號初始器清單 (4)

reflexpr-指定符 的運算元應為 類型命名空間列舉器、變數、資料成員函式參數被捕捉的實體函式呼叫表達式函式樣式類型轉換表達式,以及括號表達式。reflexpr(::) 反射全域命名空間。

對於形式為 ( 表達式 )reflexpr-運算元,該 表達式 應為(可能有多層括號的)函式呼叫表達式函式樣式類型轉換表達式

如果未加括號的運算元可以被視為 類型識別碼函式樣式類型轉換表達式,則它將被視為 類型識別碼。括號可用於區分函式樣式型別轉換和 類型識別碼。例如,給定一個帶有預設建構式的類別類型 Xreflexpr(X()) 反射函式類型 X(),而 reflexpr((X())) 反射表達式 X()

如果運算元同時指定了別名和類別名稱,則由 reflexpr-指定符 表示的類型會反射該別名並滿足 reflect::Alias

如果運算元指定了一個其宣告包含在區塊作用域中的名稱,且該具名實體既未被捕捉也不是函式參數,則程式碼格式不正確。

[編輯] 後設物件類型

一個 *後設物件類型* 是一個不具名、不完整、命名空間作用域的類別類型。一個類型當且僅當它是後設物件類型時,才滿足 reflect::Object 概念。後設物件類型可能會根據 reflexpr 的運算元滿足其他概念。

重複將 reflexpr 應用於相同的運算元是否會產生相同的類型或不同的類型是未指定的。如果後設物件類型反射一個不完整的類別類型,則某些類型轉換無法套用。

後設物件類型允許透過類型特性或類型轉換檢查 reflexpr 運算元的一些屬性。

[編輯] 多載解析

如果函式呼叫表達式中的 後置表達式 是類別類型,即 e 在函式呼叫表達式 e(args) 中是類別類型,則不應使用 後置表達式 (e) 類型的 使用者定義轉換函式

如果 後置表達式 不是類別類型,它應命名一個函式,該函式是多載解析的唯一結果。

struct Functor
{
    void operator()(int) const;
 
    using fptr_t = void(*)(std::nullptr_t);
    operator fptr_t() const;
};
 
using Meta0 = reflexpr(Functor{}(0));          // OK
// using Meta1 = reflexpr(Functor{}(nullptr)); // error: conversion function used

[編輯] 反射相關

一個 *別名* 是由 typedef 宣告、別名宣告,或 using 宣告 引入的名稱。

實體或別名 B 與實體或別名 A *反射相關*,如果

  1. AB 是相同的實體或別名,
  2. A 是變數或列舉器,而 BA 的類型,
  3. A 是列舉,而 BA 的底層類型,
  4. A 是類別,而 BA 的成員或基礎類別,
  5. A 是指定實體 B 的非模板別名,
  6. A 不是全域命名空間,而 BA 的外圍類別或命名空間,
  7. A 是括號表達式 ( B ),
  8. A 是閉包類型 B 的 Lambda 捕捉,
  9. A 是 Lambda 捕捉 B 的閉包類型,
  10. B 是由 函式樣式類型轉換表達式 A 指定的類型,
  11. B 是為 函式呼叫表達式 A 透過多載解析選定的函式,或
  12. B 是函式 A 的回傳類型、參數類型或函式類型,或
  13. B 與實體或別名 X 反射相關,且 XA 反射相關。

反射關係是自反和遞移的,但不是對稱的。

非正式地說,BA 反射相關的情況意味著 B 參與了 A 的宣告或定義。

將產生後設物件類型的零個或多個連續類型轉換應用於由 reflexpr-指定符 表示的類型,可以檢查與運算元反射相關的實體和別名;這樣的後設物件類型被稱為反射相應的反射相關實體或別名。

struct X;
struct B
{
    using X = ::X;
    typedef X Y;
};
struct D : B
{
    using B::Y;
};
// ::X, but not B::X or B::Y is reflection-related to D::Y

[編輯] 其他

  • 用作 reflexpr-運算元 的表達式是 未求值表達式可能常數求值
  • 為了確定在 Lambda 表達式中由預設捕捉 (capture-default) 捕捉的變數,reflexpr 運算元不被視為未求值運算元。
  • 由後設物件類型 T 反射的靜態 儲存期 函式或變數,會被特化 std::experimental::reflect::get_pointer<T> ODR 使用,如同取得命名該函式或變數的識別碼表達式的位址一樣。
  • 後設物件類型可以有多個定義,只要對此類型的所有操作都產生相同的常數表達式結果即可。
  • 如果類型由 reflexpr-指定符 表示,且運算元,則類型是 依賴的

[編輯] 關鍵字

reflexpr

[編輯] 預定義功能測試巨集

__cpp_reflection
(反射技術規範)
值至少為 201902 表示支援反射技術規範 (Reflection TS)
(巨集常數)

[編輯] 函式庫支援

[編輯] 概念

定義於標頭檔 <experimental/reflect>
定義於命名空間 std::experimental::reflect
定義於內聯命名空間 std::experimental::reflect::v1
(反射技術規範)
指定類型為後設物件類型
(概念)
(反射技術規範)
指定後設物件類型為後設物件序列類型
(概念)
(反射技術規範)
指定後設物件類型反射模板參數作用域
(概念)
(反射技術規範)
指定後設物件類型反射具有相關聯(可能為空)名稱的實體或別名
(概念)
(反射技術規範)
指定後設物件類型反射類型別名、命名空間別名,或由 using 宣告引入的別名
(概念)
(反射技術規範)
指定後設物件類型反射類別的 成員宣告
(概念)
(反射技術規範)
指定後設物件類型反射列舉器
(概念)
(反射技術規範)
指定後設物件類型反射變數或資料成員
(概念)
(反射技術規範)
指定後設物件類型滿足 RecordMemberEnumeratorVariable,或反射除全域命名空間以外的命名空間
(概念)
(反射技術規範)
指定後設物件類型反射具有類型的實體
(概念)
(反射技術規範)
指定後設物件類型反射命名空間
(概念)
(反射技術規範)
指定後設物件類型反射全域命名空間
(概念)
(反射技術規範)
指定後設物件類型反射非聯集類別類型
(概念)
(反射技術規範)
指定後設物件類型反射列舉類型
(概念)
(反射技術規範)
指定後設物件類型反射類別類型
(概念)
(反射技術規範)
指定後設物件類型反射命名空間、類別、列舉、函式、閉包類型、模板參數作用域
(概念)
(反射技術規範)
指定後設物件類型反射類型
(概念)
(反射技術規範)
指定後設物件類型反射列舉器或 constexpr 變數
(概念)
(反射技術規範)
指定後設物件類型反射從 get_base_classes 取得的直接基礎類別
(概念)
(反射技術規範)
指定後設物件類型反射函式參數
(概念)
(反射技術規範)
指定後設物件類型反射函式(包括建構式和解構式)
(概念)
(反射技術規範)
指定後設物件類型反射表達式
(概念)
(反射技術規範)
指定後設物件類型反射括號表達式
(概念)
(反射技術規範)
指定後設物件類型反射 函式呼叫表達式
(概念)
(反射技術規範)
指定後設物件類型反射 函式樣式類型轉換表達式
(概念)
(反射技術規範)
指定後設物件類型反射函式(不包括建構式和解構式)
(概念)
(反射技術規範)
指定後設物件類型反射成員函式(不包括建構式和解構式)
(概念)
(反射技術規範)
指定後設物件類型反射特殊成員函式
(概念)
(反射技術規範)
指定後設物件類型反射建構式
(概念)
(反射技術規範)
指定後設物件類型反射解構式
(概念)
(反射技術規範)
指定後設物件類型反射運算子函式或轉換函式
(概念)
(反射技術規範)
指定後設物件類型反射轉換函式
(概念)
(反射技術規範)
指定後設物件類型反射非泛型 Lambda 的閉包類型
(概念)
(反射技術規範)
指定後設物件類型反射 Lambda 捕捉
(概念)

[編輯] 後設物件操作

定義於標頭檔 <experimental/reflect>
定義於命名空間 std::experimental::reflect
定義於內聯命名空間 std::experimental::reflect::v1
Object 操作
(反射技術規範)
檢查兩個後設物件類型是否反射相同的實體或別名
(類別模板)
(反射技術規範)
取得被反射實體或別名宣告的推定行號
(類別模板)
(反射技術規範)
取得被反射實體或別名宣告的實作定義行號
(類別模板)
(反射技術規範)
取得被反射實體或別名宣告的推定檔名
(類別模板)
ObjectSequence 操作
(反射技術規範)
取得後設物件序列的大小
(類別模板)
(反射技術規範)
取得序列中指定索引的後設物件類型
(類別模板)
(反射技術規範)
將模板應用於後設物件序列
(類別模板)
Named 操作
(反射技術規範)
檢查被反射實體或別名是否不具名
(類別模板)
(反射技術規範)
取得被反射實體或別名的非限定名稱
(類別模板)
(反射技術規範)
取得被反射實體或別名的實作定義顯示名稱
(類別模板)
Alias 操作
(反射技術規範)
取得反射被反射別名相關聯實體的後設物件類型
(類別模板)
Type 操作
(反射技術規範)
取得反射被反射實體或別名類型的後設物件類型
(類別模板)
(反射技術規範)
取得被反射實體或別名的類型
(類別模板)
(反射技術規範)
檢查後設物件類型是否反射列舉類型
(類別模板)
(反射技術規範)
檢查後設物件類型是否反射聯集類型
(類別模板)
(反射技術規範)
檢查後設物件類型是否反射宣告分別使用 classstruct 的非聯集類別類型
(類別模板)
ScopeMember 操作
(反射技術規範)
取得反射被反射實體或別名作用域的後設物件類型
(類別模板)
Base 操作
(反射技術規範)
取得反射給定基礎類別關係中基礎類別的後設物件類型
(類別模板)
RecordMemberBase 操作
(反射技術規範)
檢查被反射成員或基礎類別是否為公開
(類別模板)
(反射技術規範)
檢查被反射成員或基礎類別是否為受保護
(類別模板)
(反射技術規範)
檢查被反射成員或基礎類別是否為私有
(類別模板)
Record 操作
取得一個後設物件序列類型,其元素反射被反射類別的公開、可存取或所有資料成員
(類別模板)
取得一個後設物件序列類型,其元素反射被反射類別的公開、可存取或所有成員函式
(類別模板)
(反射技術規範)
取得一個後設物件序列類型,其元素反射被反射類別的所有建構式
(類別模板)
(反射技術規範)
取得一個後設物件序列類型,其元素反射被反射類別中宣告的所有運算子函式和轉換函式
(類別模板)
(反射技術規範)
取得反射被反射類別解構式的後設物件類型
(類別模板)
取得一個後設物件序列類型,其元素反射被反射類別的公開、可存取或所有巢狀類型或成員 typedef
(類別模板)
取得一個後設物件序列類型,其元素反射被反射類別的公開、可存取或所有基礎類別
(類別模板)
Enum 操作
(反射技術規範)
檢查被反射列舉是否為作用域列舉
(類別模板)
(反射技術規範)
取得一個後設物件序列類型,其元素反射被反射列舉的列舉器
(類別模板)
(反射技術規範)
取得反射被反射列舉底層類型的後設物件類型
(類別模板)
Variable 操作
(反射技術規範)
取得作為常數表達式的被反射變數的值
(類別模板)
(反射技術規範)
檢查變數是否使用 thread_local 宣告
(類別模板)
FunctionParameter 操作
(反射技術規範)
檢查被反射參數是否具有預設引數
(類別模板)
Callable 操作
(反射技術規範)
取得一個後設物件序列類型,其元素反射被反射函式的參數
(類別模板)
(反射技術規範)
檢查被反射函式的參數清單是否包含省略符號參數
(類別模板)
(反射技術規範)
檢查被反射函式是否不拋出例外
(類別模板)
(反射技術規範)
檢查被反射函式是否被刪除
(類別模板)
VariableCallable 操作
(反射技術規範)
檢查被反射變數或函式是否為 constexpr
(類別模板)
NamespaceCallable 操作
(反射技術規範)
檢查被反射命名空間或函式是否為 inline
(類別模板)
ParenthesizedExpression 操作
(反射技術規範)
取得反射被反射括號表達式中未加括號表達式的後設物件類型
(類別模板)
FunctionCallExpression 操作
(反射技術規範)
取得反射被反射 函式呼叫表達式 中函式的後設物件類型
(類別模板)
FunctionalTypeConversion 操作
(反射技術規範)
取得反射被反射 函式樣式類型轉換表達式 中建構式的後設物件類型
(類別模板)
VariableFunction 操作
(反射技術規範)
取得被反射變數或函式的位址,或指向被反射非靜態成員的成員指標值
(類別模板)
MemberFunction 操作
檢查被反射成員函式是否分別使用 constvolatile&&& 限定符宣告
(類別模板)
(反射技術規範)
檢查被反射成員函式是否覆寫基礎類別的成員函式
(類別模板)
RecordMemberFunction 操作
(反射技術規範)
檢查被反射類別或成員函式是否標記為 final
(類別模板)
VariableMemberFunction 操作
(反射技術規範)
檢查被反射變數是否具有靜態儲存期,或被反射成員函式是否為靜態
(類別模板)
SpecialMemberFunction 操作
(反射技術規範)
檢查被反射特殊成員函式是否為隱式宣告
(類別模板)
(反射技術規範)
檢查被反射特殊成員函式在其首次宣告中是否預設化
(類別模板)
ConstructorConversionOperator 操作
(反射技術規範)
檢查被反射建構式或轉換函式是否使用 explicit 宣告
(類別模板)
MemberFunctionDestructor 操作
(反射技術規範)
檢查被反射成員函式是否為虛擬
(類別模板)
(反射技術規範)
檢查被反射成員函式是否為純虛擬
(類別模板)
Lambda 操作
(反射技術規範)
取得一個後設物件序列類型,其元素反射被反射閉包類型的捕捉
(類別模板)
檢查被反射閉包類型的 Lambda 表達式捕捉預設是否分別為 =&
(類別模板)
(反射技術規範)
檢查被反射閉包類型的 operator() 是否使用 const 宣告
(類別模板)
LambdaCapture 操作
(反射技術規範)
檢查被反射 Lambda 捕捉是否為明確捕捉
(類別模板)
(反射技術規範)
檢查被反射 Lambda 捕捉是否為初始化捕捉 (init-capture)
(類別模板)

[編輯] 函式庫功能測試巨集

定義於標頭檔 <experimental/reflect>
__cpp_lib_reflection
(反射技術規範)
值至少為 201902 表示支援反射技術規範 (Reflection TS) 的支援函式庫
(巨集常數)

[編輯] 概念的滿足

下表列出反射運算元的後設物件類型是否滿足反射技術規範引入的概念。

分類 reflexpr 運算元 滿足的概念
類型 指定聯集的 class-name reflect::Union
指定閉包類型的 class-name reflect::Lambda
指定非聯集類別的 class-name reflect::Record
列舉名稱 reflect::Enum
模板 類型參數 reflect::Typereflect::Alias
decltype 指定符 reflect::Typereflect::Alias
using 宣告 引入的 類型名稱 reflect::Typereflect::Aliasreflect::ScopedMember
任何其他 typedef 名稱 reflect::Typereflect::Alias
任何其他 類型識別碼 reflect::Type
命名空間 命名空間別名 reflect::Namespacereflect::Alias
全域命名空間 reflect::GlobalScope
任何其他 命名空間 reflect::Namespace
表達式 資料成員的名稱 reflect::Variable
變數的名稱 reflect::Variable
列舉器的名稱 reflect::Enumerator
函式參數的名稱 reflect::FunctionParameter
被捕捉實體的名稱 reflect::LambdaCapture
括號表達式 reflect::ParenthesizedExpression
函式呼叫表達式 reflect::FunctionCallExpression
函式樣式類型轉換表達式 reflect::FunctionalTypeConversion

如果 `識別碼表達式` 形式的運算元是常數表達式,則由 reflexpr-指定符 指定的類型也滿足 reflect::Constant

如果 `reflexpr-運算元` 指定一個類別成員,則由 reflexpr-指定符 表示的類型也滿足 reflect::RecordMember

[編輯] 參見

包含某些類型資訊,由 typeid 運算子回傳的類別
(類別) [編輯]
編譯時類型資訊公用程式[編輯]
English Deutsch 日本語 中文(简体) 中文(繁體)