Home > Mobile >  boost::pfr with customized member
boost::pfr with customized member

Time:01-21

I'm trying to use boost::pfr for basic reflection, and it fails to compile when one of the member is customized type, like a class or struct, why is this? What's the way to fix it? I'm using C 17.

// this works:
struct S1 {
    int n;
    std::string name;
};
S1 o1{1, "foobar"};
std::cout << boost::pfr::io(o1) << '\n';

// but this does not work:
struct S2 {
    int m;
    S1 s1; // <===== this fields fails to compile
};
S2 o2;
std::cout << boost::pfr::io(o2) << '\n';

CodePudding user response:

You need to provide operator<< for S1, as boost::pfr::io relies on it existing:

std::ostream& operator<<(std::ostream& os, const S1& x)
{
    return os << boost::pfr::io_fields(x);
}

live example on godbolt.org

CodePudding user response:

It is surprisingly easy to build a reflection system with modern C . Here is an example from my own library (C 20 and a WIP). NOTE: The design of this library is heavily influenced by boost fusion, which you might consider if you want to complex things in a portable C library

#include "Common/Reflection.h"
#include "Common/Json.h"
#include <utility>
#include <span>
#include <iostream>
#include <sstream>

struct Point
{
    int x, y;

    static constexpr auto get_members()
    {
        return std::make_tuple(
            Member("x", &Point::x),
            Member("y", &Point::y)
        );
    }
};

struct Line
{
    Point from, to;

    static constexpr auto get_members()
    {
        return std::make_tuple(
            Member("from", &Line::from),
            Member("to", &Line::to)
        );
    }
};

template<class T>
void ReverseEndian(T& v)
{
    const auto as_bytes = std::as_writable_bytes(std::span(&v, 1));
    std::reverse(as_bytes.begin(), as_bytes.end());
}

int main()
{
    Line l{ {0x12345678, 0x12345678}, {0x12345678, 0x12345678} };
    visit_recursive(l, [](auto& v) {ReverseEndian(v); });

    JSON(std::cout, l);
    std::cout << std::endl;

    std::istringstream is("{\"from\"={\"x\"=1}, \"to\"={\"y\"=2}}");
    JSON(is, l);
};

see https://github.com/Tiger4Hire2/NetworkingExamples

  •  Tags:  
  • Related