C++ 关键词:reflexpr (反射 TS)

来自cppreference.com
< cpp‎ | keyword
 
 
C++ 语言
 
 

用途

  1. 获取类型的成员列表,或者枚举类型的枚举列表
  2. 获得类型或成员的名称
  3. 检测成员是否是静态的,亦可以获取成员是否是一个常量表达式
  4. 检测成员函数是否为, 以及其访问级别是 publicprotected 还是 private.
  5. 获取类型定义时在源代码中的的行号或者列号

范例

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