boost::pfr 有自定义成员
boost::pfr with customized member
我正在尝试使用 boost::pfr
进行基本反射,但当其中一个成员是自定义类型(如 class 或结构)时编译失败,这是为什么?修复的方法是什么?我正在使用 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';
使用现代 C++ 构建反射系统非常容易。这是我自己的库中的示例(C++20 和一个 WIP)。
注意:这个库的设计在很大程度上受 boost fusion 的影响,如果你想在一个可移植的 C++ 库中复杂化一些东西,你可以考虑使用它
#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);
};
您需要为 S1
提供 operator<<
,因为 boost::pfr::io
依赖现有的:
std::ostream& operator<<(std::ostream& os, const S1& x)
{
return os << boost::pfr::io_fields(x);
}
我正在尝试使用 boost::pfr
进行基本反射,但当其中一个成员是自定义类型(如 class 或结构)时编译失败,这是为什么?修复的方法是什么?我正在使用 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';
使用现代 C++ 构建反射系统非常容易。这是我自己的库中的示例(C++20 和一个 WIP)。 注意:这个库的设计在很大程度上受 boost fusion 的影响,如果你想在一个可移植的 C++ 库中复杂化一些东西,你可以考虑使用它
#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);
};
您需要为 S1
提供 operator<<
,因为 boost::pfr::io
依赖现有的:
std::ostream& operator<<(std::ostream& os, const S1& x)
{
return os << boost::pfr::io_fields(x);
}