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