命名空间
变体
操作

反射扩展

来自 cppreference.com
 
 
实验性
技术规范
文件系统库 (文件系统 TS)
库基础 (库基础 TS)
库基础 2 (库基础 TS v2)
库基础 3 (库基础 TS v3)
并行扩展 (并行 TS)
并行扩展 2 (并行 TS v2)
并发扩展 (并发 TS)
并发扩展 2 (并发 TS v2)
概念 (概念 TS)
范围 (范围 TS)
反射 (反射 TS)
数学特殊函数 (特殊函数 TR)
实验性非 TS
模式匹配
线性代数
std::execution
契约
2D 图形
 
反射扩展
概念
元对象操作
变量
函数参数
可调用对象
VariableCallable
NamespaceCallable
带括号的表达式
函数调用表达式
FunctionalConversion
VariableFunction
 

C++ 反射扩展,ISO/IEC TS 23619:2021,指定了对核心语言的修改,并定义了此页面上列出的 C++ 标准库的新组件。

反射 TS 基于 C++20 标准(除了概念的定义是按照 概念 TS 的风格指定)。

内容

[编辑] 核心语言变更

[编辑] reflexpr-specifier

reflexpr-specifier 的形式为 reflexpr ( reflexpr-operand ),并指定元对象类型(见下文)。

reflexpr-operand 可以是以下之一

:: (1)
类型标识符 (2)
嵌套名称说明符(可选) 命名空间名称 (3)
标识符表达式 (4)
( 表达式 ) (5)
函数调用表达式 (6)
函数类型转换表达式 (7)

其中 函数调用表达式

后缀表达式 ( 表达式列表(可选) )

函数类型转换表达式 是执行 显式转换 的以下类型的表达式

简单类型说明符 ( 表达式列表(可选) ) (1)
类型名称说明符 ( 表达式列表(可选) ) (2)
简单类型说明符 花括号初始化列表 (3)
类型名称说明符 花括号初始化列表 (4)

reflexpr-specifier 的操作数应为 类型命名空间枚举器、变量、数据成员函数参数捕获实体函数调用表达式函数类型转换表达式 以及带括号的表达式。 reflexpr(::) 反映全局命名空间。

对于形式为 ( 表达式 )reflexpr-operand表达式 应为(可能带有多个括号的)函数调用表达式函数类型转换表达式

如果未带括号的操作数可以被视为 类型标识符函数类型转换表达式,则将其视为 类型标识符。括号可以用于区分函数风格的转换和 类型标识符。例如,给定具有默认构造函数的类类型 Xreflexpr(X()) 反映函数类型 X(),而 reflexpr((X())) 反映表达式 X()

如果操作数同时指定别名和类名,则由 reflexpr-specifier 表示的类型反映别名并满足 reflect::Alias

如果操作数指定一个声明在块作用域内的名称,并且该命名实体既未被捕获也非函数参数,则程序格式错误。

[edit] 元对象类型

元对象类型 是一个无名、不完整的命名空间作用域类类型。一个类型满足概念 reflect::Object 当且仅当它是一个元对象类型。元对象类型可以满足其他概念,具体取决于 reflexpr 的操作数。

对于同一个操作数,重复应用 reflexpr 是否产生相同类型或不同类型是未指定的。如果一个元对象类型反映一个不完整的类类型,则无法应用某些类型转换。

元对象类型允许通过类型特征或对其进行类型转换来检查 reflexpr 操作数的某些属性。

[edit] 重载解析

如果 函数调用表达式后缀表达式 为类类型,即 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

[edit] 与反射相关的

别名 是由 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-specifier 表示的类型应用产生元对象类型的零次或多次连续类型转换,可以检查与操作数相关的实体和别名;这种元对象类型被称为反映相应的相关实体或别名。

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

[edit] 其他

  • 用作 reflexpr-operand 的表达式是一个 未求值表达式 并且 可能被常量求值
  • 为了确定捕获默认值在 lambda 表达式 中捕获的变量,reflexpr 操作数不被认为是未求值的操作数。
  • 由元对象类型 T 反映的静态 存储期 函数或变量被专业化 std::experimental::reflect::get_pointer<T> 使用,就好像通过获取命名该函数或变量的 id-表达式的地址一样。
  • 可以存在多个元对象类型的定义,只要对该类型的所有操作都产生相同的常量表达式结果。
  • 一个类型是 依赖的,如果它由 reflexpr-specifier 表示,并且操作数

[edit] 关键字

reflexpr

[edit] 预定义的特性测试宏

__cpp_reflection
(反射 TS)
至少为 201902 的值表示支持反射 TS
(宏常量)

[edit] 库支持

[edit] 概念

在头文件 <experimental/reflect> 中定义
在命名空间 std::experimental::reflect 中定义
在内联命名空间 std::experimental::reflect::v1 中定义
(反射 TS)
指定类型是元对象类型
(概念)
(反射 TS)
指定元对象类型是元对象序列类型
(概念)
指定元对象类型反映模板参数作用域
(概念)
(反射 TS)
指定元对象类型反映一个带有关联(可能为空)名称的实体或别名
(概念)
(反射 TS)
指定元对象类型反映一个类型别名、命名空间别名或由 using-声明引入的别名
(概念)
(反射 TS)
指定元对象类型反映一个类的 成员声明
(概念)
(反射 TS)
指定元对象类型反映一个枚举量
(概念)
(反射 TS)
指定元对象类型反映一个变量或数据成员
(概念)
(反射 TS)
指定元对象类型满足 RecordMemberEnumeratorVariable,或者反映一个非全局命名空间
(概念)
(反射 TS)
指定元对象类型反映一个具有类型的实体
(概念)
(反射 TS)
指定元对象类型反映一个命名空间
(概念)
(反射 TS)
指定元对象类型反映全局命名空间
(概念)
(反射 TS)
指定元对象类型反映一个非联合类类型
(概念)
(反射 TS)
指定元对象类型反映一个枚举类型
(概念)
(反射 TS)
指定元对象类型反映一个类类型
(概念)
(反射 TS)
指定元对象类型反映一个命名空间、类、枚举、函数、闭包类型、模板参数作用域
(概念)
(反射 TS)
指定元对象类型反映一个类型
(概念)
(反射 TS)
指定元对象类型反映一个枚举量或一个 constexpr 变量
(概念)
(反射 TS)
指定元对象类型反映一个从 get_base_classes 获得的直接基类
(概念)
(反射 TS)
指定元对象类型反映一个函数参数
(概念)
(反射 TS)
指定元对象类型反映一个函数(包括构造函数和析构函数)
(概念)
(反射 TS)
指定元对象类型反映一个表达式
(概念)
指定元对象类型反映一个带括号的表达式
(概念)
指定元对象类型反映一个 函数调用表达式
(概念)
指定元对象类型反映一个 函数类型转换表达式
(概念)
(反射 TS)
指定元对象类型反映一个函数(不包括构造函数和析构函数)
(概念)
(反射 TS)
指定元对象类型反映一个成员函数(不包括构造函数和析构函数)
(概念)
指定元对象类型反映一个特殊成员函数
(概念)
(反射 TS)
指定元对象类型反映一个构造函数
(概念)
(反射 TS)
指定元对象类型反映一个析构函数
(概念)
(反射 TS)
指定元对象类型反映一个运算符函数或转换函数
(概念)
(反射 TS)
指定元对象类型反映一个转换函数
(概念)
指定元对象类型反映一个非泛型 lambda 的闭包类型
(概念)
(反射 TS)
指定元对象类型反映一个 lambda 捕获
(概念)

[edit] 元对象操作

在头文件 <experimental/reflect> 中定义
在命名空间 std::experimental::reflect 中定义
在内联命名空间 std::experimental::reflect::v1 中定义
Object 操作
(反射 TS)
检查两个元对象类型是否反映同一个实体或别名
(类模板)
(反射 TS)
获取反映实体或别名的声明的推测行号
(类模板)
获取反映实体或别名的声明的实现定义的列号
(类模板)
获取反映实体或别名的声明的推测文件名
(类模板)
ObjectSequence 操作
(反射 TS)
获取元对象序列的大小
(类模板)
(反射 TS)
获取序列中指定索引的元对象类型
(类模板)
(反射 TS)
将模板应用于元对象序列
(类模板)
Named 操作
(反射 TS)
检查反映的实体或别名是否无名
(类模板)
(反射 TS)
获取反映实体或别名的非限定名称
(类模板)
获取反映实体或别名的实现定义的显示名称
(类模板)
Alias 操作
(反射 TS)
获取反映反映别名的关联实体的元对象类型
(类模板)
Type 操作
(反射 TS)
获取反映反映实体或别名的类型的元对象类型
(类模板)
获取反映实体或别名的类型
(类模板)
(反射 TS)
检查元对象类型是否反映枚举类型
(类模板)
(反射 TS)
检查元对象类型是否反映联合类型
(类模板)
检查元对象类型是否反映一个非联合类类型,其声明使用 classstruct 分别。
(类模板)
ScopeMember 操作
(反射 TS)
获取反映被反射实体或别名范围的元对象类型。
(类模板)
Base 操作
(反射 TS)
获取反映给定基类关系中基类的元对象类型。
(类模板)
RecordMemberBase 操作
(反射 TS)
检查被反射的成员或基类是否为公有的。
(类模板)
(反射 TS)
检查被反射的成员或基类是否为受保护的。
(类模板)
(反射 TS)
检查被反射的成员或基类是否为私有的。
(类模板)
Record 操作
获取一个元对象序列类型,其元素反映被反射类的公有、可访问或所有数据成员。
(类模板)
获取一个元对象序列类型,其元素反映被反射类的公有、可访问或所有成员函数。
(类模板)
获取一个元对象序列类型,其元素反映被反射类所有构造函数。
(类模板)
(反射 TS)
获取一个元对象序列类型,其元素反映被反射类中声明的所有运算符函数和转换函数。
(类模板)
(反射 TS)
获取反映被反射类析构函数的元对象类型。
(类模板)
获取一个元对象序列类型,其元素反映被反射类的公有、可访问或所有嵌套类型或成员类型定义。
(类模板)
获取一个元对象序列类型,其元素反映被反射类的公有、可访问或所有基类。
(类模板)
Enum 操作
(反射 TS)
检查被反射的枚举是否为作用域的。
(类模板)
(反射 TS)
获取一个元对象序列类型,其元素反映被反射枚举的枚举器。
(类模板)
获取反映被反射枚举的底层类型的元对象类型。
(类模板)
Variable 操作
(反射 TS)
获取被反射变量的值,该变量是一个常量表达式。
(类模板)
(反射 TS)
检查变量是否用 thread_local 声明。
(类模板)
FunctionParameter 操作
检查被反射的参数是否具有默认参数。
(类模板)
Callable 操作
(反射 TS)
获取一个元对象序列类型,其元素反映被反射函数的参数。
(类模板)
(反射 TS)
检查被反射函数的参数列表是否包含省略号参数。
(类模板)
(反射 TS)
检查被反射函数是否是非抛出函数。
(类模板)
(反射 TS)
检查被反射函数是否被删除。
(类模板)
VariableCallable 操作
(反射 TS)
检查被反射的变量或函数是否为 constexpr。
(类模板)
NamespaceCallable 操作
(反射 TS)
检查被反射的命名空间或函数是否为内联的。
(类模板)
ParenthesizedExpression 操作
获取反映被反射的括号表达式中未加括号的表达式的元对象类型。
(类模板)
FunctionCallExpression 操作
(反射 TS)
获取反映被反射的 函数调用表达式 中函数的元对象类型。
(类模板)
FunctionalTypeConversion 操作
(反射 TS)
获取反映被反射的 函数类型转换表达式 中构造函数的元对象类型。
(类模板)
VariableFunction 操作
(反射 TS)
获取被反射变量或函数的地址,或指向被反射非静态成员的成员指针值。
(类模板)
MemberFunction 操作
检查被反射的成员函数是否分别用 constvolatile&&& 限定符声明。
(类模板)
(反射 TS)
检查被反射的成员函数是否重写基类的成员函数。
(类模板)
RecordMemberFunction 操作
(反射 TS)
检查被反射的类或成员函数是否用 final 标记。
(类模板)
VariableMemberFunction 操作
(反射 TS)
检查被反射的变量是否为静态存储持续时间,或者被反射的成员函数是否为静态的。
(类模板)
SpecialMemberFunction 操作
检查被反射的特殊成员函数是否为隐式声明的。
(类模板)
(反射 TS)
检查被反射的特殊成员函数是否在其首次声明中被默认为。
(类模板)
ConstructorConversionOperator 操作
(反射 TS)
检查被反射的构造函数或转换函数是否用 explicit 声明。
(类模板)
MemberFunctionDestructor 操作
(反射 TS)
检查被反射的成员函数是否为虚函数。
(类模板)
(反射 TS)
检查被反射的成员函数是否为纯虚函数。
(类模板)
Lambda 操作
(反射 TS)
获取一个元对象序列类型,其元素反映被反射闭包类型的捕获。
(类模板)
检查被反射闭包类型中 lambda 表达式的捕获默认值是否分别为 =&
(类模板)
检查被反射闭包类型的 operator() 是否用 const 声明。
(类模板)
LambdaCapture 操作
检查被反射的 lambda 捕获是否为显式捕获的。
(类模板)
(反射 TS)
检查被反射的 lambda 捕获是否为初始化捕获。
(类模板)

[edit] 库功能测试宏

在头文件 <experimental/reflect> 中定义
__cpp_lib_reflection
(反射 TS)
至少为 201902 的值表示支持反射 TS 的支持库。
(宏常量)

[edit] 满足概念

下表列出了反映操作数的元对象类型是否满足反射 TS 引入的概念。

类别 reflexpr 操作数 满足的概念
类型 类名 指定一个 联合 reflect::Union
类名 指定一个 闭包类型 reflect::Lambda
类名 指定一个非联合类 reflect::Record
枚举名 reflect::Enum
模板 类型参数 reflect::Type, reflect::Alias
decltype-specifier reflect::Type, reflect::Alias
类型名using-declaration 引入 reflect::Type, reflect::Alias, reflect::ScopedMember
任何其他 typedef-name reflect::Type, reflect::Alias
任何其他 type-id reflect::Type
命名空间 命名空间别名 reflect::Namespace, reflect::Alias
全局命名空间 reflect::GlobalScope
任何其他 命名空间 reflect::Namespace
表达式 数据成员的名称 reflect::Variable
变量的名称 reflect::Variable
枚举器的名称 reflect::Enumerator
函数参数的名称 reflect::FunctionParameter
捕获实体的名称 reflect::LambdaCapture
括号表达式 reflect::ParenthesizedExpression
函数调用表达式 reflect::FunctionCallExpression
函数类型转换表达式 reflect::FunctionalTypeConversion

如果 id-expression 形式的操作数是一个常量表达式,则 reflexpr-specifier 指定的类型也满足 reflect::Constant

如果 reflexpr-operand 指定一个类成员,则 reflexpr-specifier 表示的类型也满足 reflect::RecordMember

[edit] 另请参阅

包含一些类型的 信息,即 typeid 运算符返回的类。
(class) [edit]
编译时类型信息实用程序[edit]