是否有一种方法可以获得表示boost::hana
结构反射的对象,我可以传递该反射并将其存储在地图/数据库中?
我正在创建一个环境和共享库之间的接口,这些库是作为插件动态加载的。我需要反映库中使用的一些数据结构,以便用户能够在运行时使用环境导航这些结构。
在一个例子中,我有这样的结构,可以很容易地反映出来:
struct Car {
BOOST_HANA_DEFINE_STRUCT(Car,
(std::string, brand),
(std::string, model)
);
};
我的库将创建一个Car
实例,并需要通过一个入口点提供它。这意味着它需要坚持从我的环境SDK实现一个基类,它看起来有点像这样:
template<class SharedStructureType>
class LibraryAPI
{
public:
virtual void run() = 0; // Some entrypoint called by the environment
ReflectedType GetReflection()
{
return to_reflection(m_sharedData);
}
protected:
SharedStructureType m_sharedData;
private:
ReflectedType to_reflection(SharedStructureType);
};
我的问题是我不知道如何实现LibraryAPI::to_reflection
。
当一个结构被boost::hana反射时,我希望看到创建了一些对象或成员,这些对象或成员表示反射规则,这就是我希望通过接口传递的内容。但是,调试器没有显示类似的内容。
我怀疑这一切都是在编译时解析的巨型模板中解决的。但是,我的环境和库不会同时被编译,这使得事情变得更加复杂。
是否有一种方法可以获得一个表示boost的对象::hana结构反射,我可以传递它并存储在一个地图/数据库中?
我并不像关心库所使用的每个成员的名称、偏移量和大小一样关心去引用数据。这将允许我使用环境来根据配置在库之间映射数据,而不需要在库之间共享头文件。我可以在反射中添加类型,作为在实际执行之前验证memcpy的一种方法。
不幸的是,在调试器中运行时,bmw.brand
和boost::hana::second(pair)
从未占用相同的内存。
Car bmw{"BMW", "Z3"};
boost::hana::for_each(bmw, [&](auto pair) {
if(&bmw.brand == &boost::hana::second(pair)
// We never get here
int i;
});
发布于 2018-01-19 06:18:54
直接在结构上折叠时得到的对的问题是,它们包含第二部分中成员的副本,这就是为什么它们不占用与实例相同的内存。
正如注释中所建议的那样,hana::accessors
,折叠为包含名称和函数的对,接受实例并返回对相应成员的引用。
也许这与你想要做的事情很接近:
#include <array>
#include <boost/hana.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace hana = boost::hana;
struct Car {
BOOST_HANA_DEFINE_STRUCT(Car,
(std::string, brand),
(std::string, model),
(std::array<char, 4>, year)
);
};
struct member_meta
{
std::string name;
std::size_t offset;
std::size_t size;
};
int main() {
Car bmw{"BMW", "Z3", {'2', '0', '1', '0'}};
std::vector<member_meta> bmw_meta{};
hana::for_each(hana::accessors<Car>(), [&](auto pair)
{
bmw_meta.push_back(member_meta{
std::string(hana::to<char const*>(hana::first(pair)))
, reinterpret_cast<size_t>(&hana::second(pair)(bmw)) - reinterpret_cast<size_t>(&bmw)
, sizeof(hana::second(pair)(bmw))
});
});
for (auto const& x : bmw_meta)
{
std::cout << x.name << ' ' << x.offset << ' ' << x.size << '\n';
}
}
https://stackoverflow.com/questions/48318957
复制相似问题