C++ 关键词:reflexpr
(反射 TS)
来自cppreference.com
用法
- 获取类类型的成员列表,或者枚举类型的枚举列表。
- 获得类型或成员的名称。
- 检测成员是否是静态的,亦可以获取成员是否是 constexpr 的。
- 检测成员函数是否为虚, 以及其访问级别是 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; }; // 反射 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>); // 成功 int main() {}
通过 reflexpr
,我们也可以获取名称信息:
运行此代码
#include <iostream> #include <string> #include <string_view> // 反射 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"); // 成功 }
这是在反射 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,而非 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,而非 Spam