Namespaces
Variants

C++ keyword: reflexpr (reflection TS)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

用法

1) 获取 class 类型的成员列表,或 enum 类型的枚举器列表。
2) 获取类型和成员的名称。
3) 检测数据成员是否为 static constexpr
4) 检测成员函数是否为 virtual 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 <iostream>
#include <string>
#include <string_view>
// 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
}

这是获取 反射技术规范 中类型 作用域 的示例。

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