C++ 关键词:reflexpr (反射 TS)
来自cppreference.com
C++ 语言
| 一般主题 | |||||||||||
| 流程控制 | |||||||||||
| 条件执行语句 | |||||||||||
| 重复语句(循环) | |||||||||||
| 跳转语句 | |||||||||||
| 函数 | |||||||||||
| 函数声明 | |||||||||||
| Lambda 函数声明 | |||||||||||
inline 说明符
|
|||||||||||
| 动态异常说明 (C++20 前) | |||||||||||
noexcept
说明符 (C++11) |
|||||||||||
| 异常 | |||||||||||
| 命名空间 | |||||||||||
| 类型 | |||||||||||
| 说明符 | |||||||||||
|
|||||||||||
| 存储期说明符 | |||||||||||
| 初始化 | |||||||||||
| 表达式 | ||||||||||||||||
| 替代表示 | ||||||||||||||||
| 字面量 | ||||||||||||||||
| 布尔 - 整数 - 浮点 | ||||||||||||||||
| 字符 - 字符串 - nullptr (C++11) | ||||||||||||||||
| 用户定义 (C++11) | ||||||||||||||||
| 工具 | ||||||||||||||||
| 属性 (C++11) | ||||||||||||||||
| 类型 | ||||||||||||||||
typedef 声明
|
||||||||||||||||
| 类型别名声明 (C++11) | ||||||||||||||||
| 类型转换 | ||||||||||||||||
| 隐式转换 - 显式转换 | ||||||||||||||||
| static_cast - dynamic_cast | ||||||||||||||||
| const_cast - reinterpret_cast | ||||||||||||||||
| 内存分配 | ||||||||||||||||
| 类 | ||||||||||||||||
| 特定于类的函数性质 | ||||||||||||||||
|
||||||||||||||||
| 特殊成员函数 | ||||||||||||||||
| 模板 | ||||||||||||||||
| 杂项 | ||||||||||||||||
关键词
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 具有特殊含义的标识符 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
用途
- 获取类类型的成员列表,或者枚举类型的枚举列表
- 获得类型或成员的名称
- 检测成员是否是静态的,亦可以获取成员是否是一个常量表达式
- 检测成员函数是否为虚, 以及其访问级别是 public、 protected 还是 private.
- 获取类型定义时在源代码中的的行号或者列号
范例
reflexpr 可以通过带有元信息的对象类型来获取对象的元数据 . 使用
std::reflect::get_data_members_t 可以访问类的反射信息,就如同使用 std::tuple 一般
运行此代码
#include <string> #include <vector> struct S { int b; std::string s; std::vector<std::string> v; }; // Reflection TS #include <experimental/reflect> using meta_S = reflexpr(S); using mem = std::reflect::get_data_members_t<meta_S>; using meta = std::reflect::get_data_members_t<mem>; static_assert(std::reflect::is_public_v<meta>); // successful int main() {}
通过 reflexpr,我们也可以获取类型的名称信息:
运行此代码
#include <string> #include <string_view> #include <iostream> // Reflection TS #include <experimental/reflect> template <typename Tp> constexpr std::string_view nameof() { using TpInfo = reflexpr(Tp); using aliased_Info = std::experimental::reflect::get_aliased_t<TpInfo>; return std::experimental::reflect::get_name_v<aliased_Info>; } int main(){ std::cout << nameof<std::string>() << '\n'; static_assert(nameof<std::string>() == "basic_string"); // successful }
这是在反射 TS中获取类型所在命名空间的示例。
运行此代码
namespace Foo{ struct FooFoo{int FooFooFoo}; } namespace Bar{ using BarBar = ::Foo::FooFoo; } using BarBarInfo = reflexpr(::Bar::BarBar); using BarBarScope = ::std::experimental::reflect::get_scope_t<BarBarInfo>; // Bar, not Foo struct Spam{int SpamSpam;}; struct Grok{ using GrokGrok = Spam::SpamSpam; }; using GrokGrokInfo = reflexpr(::Grok::GrokGrok); using GrokGrokScope = std::experimental::reflect::get_scope_t<GrokGrokInfo>; // Grok, not Spam