# C++ 关键词：reflexpr (反射 TS)

< cpp‎ | keyword

### 用途

1. 获取类类型的成员列表，或者枚举类型的枚举列表
2. 获得类型或成员的名称
3. 检测成员是否是静态的，亦可以获取成员是否是一个常量表达式
4. 检测成员函数是否为虚, 以及其访问级别是 public、 protected 还是 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