- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 boost:serialization 将数据结构保存到文件中。实际数据是类和子类的指针 vector 。然而,被序列化的类的构造函数将另一个实例化类 Agent 作为参数,它是一个控制与模拟 API (webots) 通信的对象。我在 boost::serialization 示例中看到,可序列化对象需要一个空的构造函数 class() {};用于重建。然而,这对我来说是不切实际的。我如何使用重建但包含与 API 通信的对象?其中一个可序列化类具有此构造函数:
State(Agent &A, ACTION_MODE const& m);
并且我从 boost 文档中的示例中看到我需要这样的东西:
State() {};
但是 Agent &A 必须作为参数传递。我应该找到解决这个问题的方法(使用外部、单例、全局对象)还是有办法在重建时修改这种行为?我确定我在这里遗漏了一些东西。
谢谢
编辑:也许我没有足够清楚地解释这一点。尝试通过重构序列化数据“加载”时收到错误消息。
error: no matching function to call State::State()
这让我研究了 boost::serialize 代码,并认为它正在调用构造函数或复制运算符。我如何让它使用特定的构造函数来序列化数据并将代理引用 &a 作为参数?
编辑#2:
template <class S, class P, class A> void Task<S,P,A>::save(const char* file)
{
std::ofstream ofs(file);
assert(ofs.good());
boost::archive::text_oarchive oa(ofs);
oa << states;
ofs.close();
}
template <class S, class P, class A> void Task<S,P,A>::load(const char* file)
{
std::ifstream ifs(file);
boost::archive::text_iarchive ia(ifs);
ia >> states;
ifs.close();
}
States 是 boost::serialization::access 的 friend ,并且有一个函数 serialize。保存工作正常,加载是问题。状态是:boost::ptr_vector<S> states;
其中 S 是一种 State 多态类。
State是基类,有“serialize”
template <class Archive>
void State::serialize(Archive& ar, const unsigned int version)
{
ar & accel.Xaxis & accel.Yaxis & accel.Zaxis;
ar & gyro.Xaxis & gyro.Yaxis & gyro.Zaxis;
ar & gps.Yaxis;
ar & positions;
ar & reward & value & hash_value;
}
guState 继承自 State。
template <class Archive>
void guState::serialize(Archive& ar, const unsigned int version)
{
ar & boost::serialization::base_object<State>(*this);
ar & accel.Xaxis & accel.Yaxis & accel.Zaxis;
ar & gyro.Xaxis & gyro.Yaxis & gyro.Zaxis;
ar & gps.Yaxis;
ar & positions;
ar & reward & value & hash_value;
}
accel、gyro、gps 是具有 3 个 double 变量的简单结构。他们在上面连载^^。职位是 std::map<std::string,float> positions;
查看序列化文本文件,一切正常。我不明白为什么它在尝试加载文件时调用构造函数。
编辑#3:
基础构造函数是:
State(Agent &A, ACTION_MODE const& m);
派生构造函数是:
guState::guState(Agent& A, ACTION_MODE const& m) :
State(A, m)
{
...
}
代理引用 &A,保存在每个状态(或派生状态)中,指的是从模拟 API 中获得的对象。它控制着一个机器人。我不能序列化它,序列化它也没有意义。
当我使用时:
namespace boost { namespace serialization {
template <class Archive>
void save_construct_data(Archive & ar,const guState* d,const unsigned int file_version)
{
ar << guState::caller;
ar << guState::mode;
}
template <class Archive>
void load_construct_data(Archive & ar, guState* d,const unsigned int file_version)
{
Agent &a;
ACTION_MODE &m;
ar >> a;
ar >> m;
::new(d) guState(a,m);
}
}
}
我收到以下错误:
invalid use of non-static data member State::caller
invalid use of non-static data member State::mode
引用从构造函数中使用的引用。并且:
error: 'a' declared as reference but not initialized
error: 'm' declared as reference but not initialized
如您所见,尝试保存对 Agent 的引用是没有意义的,因为每次启动应用程序时该引用(即使它可以保存或序列化)都可能不同。
并且在加载构造数据时,除了我可能使用了错误的语法外,从对代理的序列化引用构造是没有意义的。
我相信我需要的是一种方法来告诉 load_construct_data 如何获取对代理的引用(在初始化代理对象之后)并使用该引用来构造数据。
这有意义吗?你认为这可行吗?
编辑#4
namespace boost { namespace serialization {
template <class Archive>
void save_construct_data(Archive & ar,const guState* d,const unsigned int file_version)
{
ar << guState::caller;
}
template <class Archive>
void load_construct_data(Archive & ar, guState* d,const unsigned int file_version)
{
Agent * a;
ACTION_MODE mode = RAND_SING;
ar >> a;
::new(d) guState(*a,mode);
}
}
}
不允许序列化 guState::caller
我还使类 Agent 可序列化,并重载了 Agent 的 load_construct_data 和 save_construct_data,以便从模拟应用请求一个新的 Agent 实例来控制 API。
最佳答案
编辑:
我认为我们都错过了手册的一部分:非默认构造函数 here .要使其正常工作,您需要一个 save_construct_data
和一个 load_construct_data
函数。在探索这些 friend 的地方方面存在轻微的技术问题 here .
此外,您说您在尝试仅加载时遇到了这个问题,但您可以保存。这让我觉得你可能忽略了
BOOST_CLASS_EXPORT_GUID(state, "state")
这种遗漏可能会在您进行负载编译后导致段错误(请参阅手册的导出部分)
为了确保我没有弄错,我做了一个编译示例,我添加它以防它有用。
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/export.hpp>
#include <iostream>
#include <fstream>
//base class
struct base
{
base(double d) : m_d(d) {}
virtual double run() = 0;
private:
friend class boost::serialization::access;
double m_d;
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & m_d;
}
};
//forward declare the save construct data before friending it
// (something about friend being in a different namespace)
class derived;
namespace boost { namespace serialization {
template<class Archive>
inline void save_construct_data(Archive & ar, const derived * t, const unsigned int file_version);
}}
//derived class with non-default constructor
struct derived : public base
{
derived(double a , double b) :
base(a+b),
m_a(a),m_b(b),m_c(a*b)
{}
//some checks
double get_a() const {return m_a;}
double get_b() const {return m_b;}
double get_c() const {return m_c;}
double run(){return 1.0;}
private:
friend class boost::serialization::access;
template<class Archive>
friend void boost::serialization::save_construct_data(Archive & ar, const derived * t, const unsigned int file_version);
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & boost::serialization::base_object<base>(*this);
//only need to return c, a and b already done for constructor
ar & m_c;
}
double m_a, m_b, m_c;
};
//Save and load the data required for the constructor.
namespace boost { namespace serialization {
template <class Archive>
inline void save_construct_data(
Archive & ar,const derived* d,const unsigned int file_version
)
{
// save data required to construct instance
ar << d->m_a;
ar << d->m_b;
}
template <class Archive>
inline void load_construct_data(
Archive & ar, derived* d,const unsigned int file_version
)
{
double a,b;
ar >> a;
ar >> b;
// invoke inplace constructor to initialize instance of my_class
::new(d) derived(a,b);
}
}
}
//register the derived class with boost.
BOOST_CLASS_EXPORT_GUID(derived, "derived")
int
main (int ac, char **av)
{
std::ofstream ofs("filename");
base* p = new derived(2,3);
// save data to archive
{
boost::archive::text_oarchive oa(ofs);
oa << p;
}
// ... some time later restore the class instance to its orginal state
base* p2;
{
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
ia >> p2;
}
derived* d = static_cast<derived*>(p2);
std::cout<<"p2 vals are: "<<d->get_a()<<" "<<d->get_b()<<" "<<d->get_c()<<std::endl;
}
旧回复:
不确定我是否完全理解您的问题(更完整的示例会对我有所帮助)-序列化对象时通常不会使用构造函数:序列化原始数据?
你的意思是不想序列化对象的所有原始数据,而只是想在反序列化对象(使用构造函数)时再次重构它?如果是这样,那么您可以通过序列化重建所需的数据并拆分保存和加载操作来实现这一点。
struct my_class
{
my_class(Agent& A, ACTION_MODE const & m)
: m_state(A,M)
{}
private:
State m_state;
friend class boost::serialization::access;
void save(Archive & ar, const unsigned int version) const
{
// note, version is always the latest when saving
Agent tmp_A = m_state.get_A();
ACTION_MODE tmp_m = m_state.get_m();
ar & tmp_A;
ar & tmp_m;
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
Agent tmp_A;
ACTION_MODE tmp_m
ar & tmp_A;
ar & tmp_m;
m_state = State(tmp_A,tmp_m);
}
BOOST_SERIALIZATION_SPLIT_MEMBER()
}
这有帮助吗,还是我没捕获要点?
关于c++ - 提升 :serialization reconstruction (loading),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6734814/
题目地址:https://leetcode.com/problems/reconstruct-itinerary/description/ 题目描述 Given a list of airline
题目地址:https://leetcode.com/problems/queue-reconstruction-by-height/#/descriptionopen in new window 题
我已经用两个相机的固有相机矩阵成功计算了旋转、平移。我还从左右摄像头获得了校正后的图像。现在,我想知道如何计算一个点的 3D 坐标,只是图像中的一个点。在这里,请看绿点。我看了一下方程,但它需要我不知
我正在使用 boost:serialization 将数据结构保存到文件中。实际数据是类和子类的指针 vector 。然而,被序列化的类的构造函数将另一个实例化类 Agent 作为参数,它是一个控制与
我正在使用 RESTEasy 来使用 REST 服务,我正在尝试使用 Twitter 的搜索 API。 所以我创建了这个界面: public interface SimpleClient { @G
题目地址:https://leetcode.com/problems/reconstruct-original-digits-from-english/description/ 题目描述: Giv
我有这些数据类型: data PointPlus = PointPlus { coords :: Point , velocity :: Vector } deriving (
我的目的是通过另一个 Hermes2 向 MSH (Hermes2 http://www.cecid.hku.hk/hermes.php ) 发送 ebxml 消息。 我正在发送相当简单的消息(没有附
我是 opencv 库的初学者。我已经在 Ubuntu 17.04 上安装了它,安装过程中的一切都很完美,一点错误都没有。我已经安装了 Opencv-master,构建了它,然后我下载了 opencv
我目前正在尝试从NERF模型重建网格,我注意到大多数NERF实现都提供了一个Python脚本,用于通过COLMAP从图像中提取相机姿势。我的理解是,这些脚本使用稀疏重建,或者至少使用COLMAP的特征
我正在将 ARKit 与 SceneKit 结合使用,并想让我的 3D 对象与 reconstructed scene 物理交互由带有 LiDAR 传感器的设备创建 (config.sceneReco
我正在回答下面的问题。 序列 [0, 1, ..., N] 被打乱了,你对它的顺序的唯一线索是一个数组,表示每个数字是大于还是小于最后一个。给定这些信息,重建一个与其一致的数组。 例如,给定 [Non
映射任意时髦的嵌套列表的最简单方法是什么expr到函数 unflatten以便 expr==unflatten@@Flatten@expr ? 动机:Compile只能处理完整的数组(我刚学到的东西—
typedef struct { union { uint32_t ss32; struct { unsigned int res
我刚开始学习 Rx,并尝试使用 SerialPort 从 GPS 设备实现“NMEA 句子阅读器”。事实上,它的 GPS 数据对这个问题来说不太重要,所以让我们澄清一下 NMEA 格式由线条组成,“$
If you want to keep your Neural Network architecture secret and still want to use it in an applic
If you want to keep your Neural Network architecture secret and still want to use it in an applic
我不知道在这里问这个问题是否合适,如果不合适,请见谅。 我得到了一个序列 ALPHA,例如: A B D Z A B X 我得到了 ALPHA 的子序列列表,例如: A B D B D A B D Z
我有这两个二叉树序列(不是 BSD): 顺序:3 2 1 4 5 7 6 后序:3 1 2 5 6 7 4 我们知道postOrder中的最后一个元素是根,所以我们把根定位在inOrder序列上,这样
我是一名优秀的程序员,十分优秀!