我正在使用谷物,一个 C++11 序列化库。我不确定这是库的错误还是我如何使用它的问题,我需要一些帮助。
鉴于以下对我自己的代码具有代表性(但不依赖于)的最小重现,我收到 JSONInputArchive::search 引发的异常,正如下面代码示例中我的评论旁边的行所调用的那样(//breaks here。)
我目前在这个 github repro 中提交436a0a275cda007f137876f37b4fc8783e615352(在撰写本文时,他们的开发分支的提示。)
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include "cereal/cereal.hpp"
#include "cereal/types/map.hpp"
#include "cereal/types/vector.hpp"
#include "cereal/types/memory.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/base_class.hpp"
#include "cereal/archives/json.hpp"
#include <cereal/types/polymorphic.hpp>
class BaseClass : public std::enable_shared_from_this<BaseClass> {
public:
virtual ~BaseClass(){}
template <class Archive>
void serialize(Archive & archive){
archive(CEREAL_NVP(name), CEREAL_NVP(baseMember));
}
protected:
BaseClass(const std::string &a_name):
name(a_name){
}
std::string name;
int baseMember; //let this have random junk so we can see if it saves right.
};
class DerivedClass : public BaseClass {
friend cereal::access;
public:
static std::shared_ptr<DerivedClass> make(const std::string &a_name, int a_derivedMember){
return std::shared_ptr<DerivedClass>(new DerivedClass(a_name, a_derivedMember));
}
template <class Archive>
void serialize(Archive & archive){
archive(CEREAL_NVP(derivedMember), cereal::make_nvp("base", cereal::base_class<BaseClass>(this)));
}
private:
DerivedClass(const std::string &a_name, int a_derivedMember):
BaseClass(a_name),
derivedMember(a_derivedMember){
}
template <class Archive>
static DerivedClass * load_and_allocate(Archive &archive){
int derivedMember;
archive(CEREAL_NVP(derivedMember)); //breaks here.
DerivedClass* object = new DerivedClass("", derivedMember);
archive(cereal::make_nvp("base", cereal::base_class<BaseClass>(object)));
return object;
}
int derivedMember;
};
CEREAL_REGISTER_TYPE(DerivedClass);
void saveTest(){
std::stringstream stream;
{
cereal::JSONOutputArchive archive(stream);
auto testSave = DerivedClass::make("TestName", 4);
archive(cereal::make_nvp("test", testSave));
}
std::cout << stream.str() << std::endl;
std::shared_ptr<DerivedClass> loaded;
{
cereal::JSONInputArchive archive(stream);
archive(cereal::make_nvp("test", loaded));
}
std::stringstream stream2;
{
cereal::JSONOutputArchive archive(stream2);
archive(cereal::make_nvp("test", loaded));
}
std::cout << stream2.str() << std::endl;
std::cout << "TA-DA!" << std::endl;
}
int main(){
saveTest();
}
我从上面得到的示例输出(在异常之前)是:
{
"test": {
"id": 1073741824,
"ptr_wrapper": {
"id": 2147483649,
"data": {
"derivedMember": 4,
"base": {
"name": "TestName",
"baseMember": -1163005939
}
}
}
}
}
我已经修改了 throwing 方法(在 grain/archive/json.hpp 中)以打印它正在搜索的内容以及它正在查看的每个值以调试问题。这是我的修改版本:
//! Adjust our position such that we are at the node with the given name
/*! @throws Exception if no such named node exists */
inline void search( const char * searchName )//, GenericValue const & parent )
{
size_t index = 0;
std::cout << "_____" << std::endl;
for( auto it = itsMemberItBegin; it != itsMemberItEnd; ++it, ++index )
if( std::strcmp( searchName, it->name.GetString() ) == 0 )
{
itsIndex = index;
return;
} else{
//I added this part here
std::cout << "!" << searchName << " == " << it->name.GetString() << std::endl;
}
throw Exception("JSON Parsing failed - provided NVP not found");
}
上述方法的输出之前除外:
!derivedMember == id
!derivedMember == data
我从中得到的输出似乎表明搜索正在查看“test.ptr_wrapper”的成员而不是“test.ptr_wrapper.data”。
我的问题是:我做错了什么吗?还是麦片有问题?