2024/10/3

C++ Reflection

忘記列出library source 了...
這是別人的 library.

struct Node {
    std::string key;
    int value;
    std::vector<Node> children;

    REFLECT()       // Enable reflection for this type
};
REFLEC( ) 是:
define REFLECT() \
    friend struct reflect::DefaultResolver; \
    static reflect::TypeDescriptor_Struct Reflection; \
    static void initReflection(reflect::TypeDescriptor_Struct*);

所以是在 structure 中增加一個 static variable 和 一個function
Reflection,
initReflection()
然後還有宣告
/ Define Node's type descriptor
REFLECT_STRUCT_BEGIN(Node)
REFLECT_STRUCT_MEMBER(key)
REFLECT_STRUCT_MEMBER(value)
REFLECT_STRUCT_MEMBER(children)
REFLECT_STRUCT_END()
就是依序把Node struct 的 member 宣告一下。
這部份解開就是
    reflect::TypeDescriptor_Struct Node::Reflection{type::initReflection}; 
    void Node::initReflection(reflect::TypeDescriptor_Struct* typeDesc) { 
        using T = Node; 
        typeDesc->name = "Node"; 
        typeDesc->size = sizeof(Node); 
        typeDesc->members = {
        
            {"key",      offsetof(Node, key),      reflect::TypeResolver<std:tring>::get()},
            {"value",    offsetof(Node, value),    reflect::TypeResolver<int>::get()},
            {"children", offsetof(Node, children), reflect::TypeResolver<std:vector<Node>>::get()},
            
        };
    }
main( ) 在告完 Node 變數後,就呼叫:
   reflect::TypeDescriptor* typeDesc = reflect::TypeResolver<Node>::get();
看一下 reflect::TypeResolver<Node>::get*(),template 展開
struct TypeResolver {
    static TypeDescriptor* get() {
        return DefaultResolver::get<Node>();
    }
};
DefaultResolver:get 也是 template:
// This version is called if T has a static member named "Reflection":
    template <typename T, typename std::enable_if<IsReflected<T>::value, int>::type = 0>
    static TypeDescriptor* get() {
        return &T::Reflection;
    }

    // This version is called otherwise:
    template <typename T, typename std::enable_if<!IsReflected<T>::value, int>::type = 0>
    static TypeDescriptor* get() {
        return getPrimitiveDescriptor<T>();
    }
先解開
template <typename T, typename std::enable_if<IsReflected<T>::value, int>::type = 0>
用 std::enable_if 來區分要用那一個
std::enable_if<IsReflected<T>::value, int>::type = 0
enable_if 的 boolean 是 IsRlected<T>::value
IfReflected 是
    struct IsReflected {
        enum { value = (sizeof(func<T>(nullptr)) == sizeof(char)) };
    };
value 的值是 true or false:
(sizeof(func<T>(nullptr)) == sizeof(char)) 
func<T>(nullptr) 有兩個定義,由 T 沒有 member variable : Reflection 決定。Node 有,所以func 是..
template <typename T> static char func(decltype(&T::Reflection));
所以是sizeof(char),所以 value 是 true,也就是 IsReflected<Node>::value 是 true
配合 std::enable_if 用...
   template <typename T, typename std::enable_if<IsReflected<T>::value, int>::type = 0>
    static TypeDescriptor* get() {
        return &T::Reflection;
    }
所以是main( ) 中呼叫 :: get( ) 會回傳,Node::Reflection

之後 typeDesc->dump(&node);
就是 static reflect::TypeDescriptor_Struct 的 dump() :
    virtual void dump(const void* obj, int indentLevel) const override {
        std::cout << name << " {" << std::endl;
        for (const Member& member : members) {
            std::cout << std::string(4 * (indentLevel + 1), ' ') << member.name << " = ";
            member.type->dump((char*) obj + member.offset, indentLevel + 1);
            std::cout << std::endl;
        }
        std::cout << std::string(4 * indentLevel, ' ') << "}";
    }

沒有留言:

張貼留言