如何在编译时或运行时获取 属性 名称和 class 中的偏移量?

How to get a property name and offset in a class at compile time or runtime?

我有一个 class 名为 SoftInfo。

class SoftInfo
{
  public:

    std::string m_strSoftName;

    std::string m_strSoftVersion;

    std::string m_strInstallLocation;
}

我想通过 sol3 在 c++ 程序中将其导出到 lua。我写了这样的东西,我可以在 lua 世界中使用它。但是,有一些不方便。我需要写 class SoftInfo 的任何 属性 的名称和偏移量。当我在 SoftInfo 中更改 属性 名称时,我还需要在函数 Export 中更改名称。另外,如果SoftInfo的属性太多,手动写Export函数会很吃力。

void Export(lua_state _state)
{
 _state.new_usertype<SoftInfo>("SoftInfo", 
   "m_strSoftName",&SoftInfo::m_strSoftName,
"m_strSoftVersion",&SoftInfo::m_strSoftVersion,
"m_strInstallLocation",&SoftInfo::m_strInstallLocation);
}

void Export(lua_state _state)
{
        sol::usertype<SoftInfo> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
        usertype_table["m_strSoftName"] = &SoftInfo::m_strSoftName;
        usertype_table["m_strSoftVersion"] = &SoftInfo::m_strSoftVersion;
        usertype_table["m_strInstallLocation"] = &SoftInfo::m_strInstallLocation;
}

我想知道有没有办法避免像宏这样的复杂工作,我可以写这样的东西?如果其他解决方案可以减少复杂的手动工作,则不限于我在下面提供的解决方案模式。

class SoftInfo
{
  public:
    //Macro or something defined here
    std::string m_strSoftName;

    std::string m_strSoftVersion;

    std::string m_strInstallLocation;
}

void Export(lua_state _state)
{
 sol::usertype<ship> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
 for(auto [properties,offset]:Func(SoftInfo))
     usertype_table[properties] = offset;
}

您要求的是静态反射。不幸的是,C++ 没有。但是,使用 boost describe,您可能会非常接近

#include<boost/describe.hpp>

BOOST_DESCRIBE_STRUCT(SoftInfo, (),
    (m_strSoftName,
     m_strSoftVersion,
     m_strInstallLocation))

void Export(lua_state _state)
{
    sol::usertype<SoftInfo> usertype_table = _state.new_usertype<SoftInfo>("SoftInfo");
    using namespace boost::describe;
    using M = describe_members<SoftInfo, mod_any_access>;
    boost::mp11::mp_for_each<M>([&](auto d){
        using D = decltype(d);
        usertype_table[D::name] = D::pointer;
    });
}

BOOST_DESCRIBE_STRUCT 必须通过填写所有成员手动维护,但 Export 将自动执行。