Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[struct_xml] struct_xml::to_xml一个包含std::map<int, int>的对象,执行struct_xml::to_xml时崩溃。且不能支持struct_pack::compatible做成员变量 #780

Open
xiaocai123123 opened this issue Sep 21, 2024 · 3 comments

Comments

@xiaocai123123
Copy link

代码如下

#include <cassert>
#include <iostream>

#include "ylt/struct_xml/xml_reader.h"
#include "ylt/struct_xml/xml_writer.h"
#include <ylt/struct_pack.hpp>

struct person {
	std::string name;
	int age;
	std::list<int> list;
	std::vector<int> vec;
	std::map<int, int> idx2Int;
	//struct_pack::compatible<int, 114514> c1;
};

bool operator==(const person& a, const person& b) {
	return a.name == b.name && a.age == b.age;
}

YLT_REFL(person, name, list, age, vec, idx2Int/*, c1*/);

int main() {
	person p{ "tom", 20 , {1,2,3}, {1,2,3}, { {1, 11}, {2, 21}} /*, 11*/ };
	std::string str;

	// struct to xml
	struct_xml::to_xml<true>(p, str);
	std::cout << str << "\n";

	// struct from xml
	person p1;
	struct_xml::from_xml(p1, str);
	assert(p1.name == p.name);
	return 0;
}

问题1,因为person里有成员变量std::map<int, int> idx2Int,所以执行到struct_xml::to_xml(p, str);时崩溃。崩溃如下图
image
问题2,如果打开struct_pack::compatible<int, 114514> c1;相关的注释,编译不通过,编译报错如下图
image

因为我想让结构体person同时使用struct_pack、struct_xml、struct_json,且想保证不同版本的前后兼容性。且能支持std常用的容器,如std::map。谢谢!

@qicosmos
Copy link
Collaborator

xml是不支持map的,没有xml结构可以和map对应,map只是用来保存属性才能用而不是直接作为成员,可以看看struct_xml 的例子,如果字段中有map类型则会抛出一个bad function call的异常。

https://github.com/qicosmos/iguana/blob/master/test/test_xml.cpp#L774

@qicosmos
Copy link
Collaborator

这个对象to_json 是没问题的,因为json支持map结构。

@xiaocai123123
Copy link
Author

xml是不支持map的,没有xml结构可以和map对应,map只是用来保存属性才能用而不是直接作为成员,可以看看struct_xml 的例子,如果字段中有map类型则会抛出一个bad function call的异常。

https://github.com/qicosmos/iguana/blob/master/test/test_xml.cpp#L774

感谢答复!
json是可以支持std::map的,我测试过。xml的话,我刚试过了boost的序列化,也是可以支持的。boost测试代码如下

#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/xml_iarchive.hpp> 
#include <boost/serialization/list.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <iostream> 
#include <fstream> 
#include <list> 
#include <vector> 
#include <map> 
struct person {
	std::string name;
	int age;
	std::list<int> list;
	std::vector<int> vec;
	std::map<int, int> idx2Int;
	//struct_pack::compatible<int, 114514> c1;
};
namespace boost {
	namespace serialization {

		template<class Archive>
		void serialize(Archive& archive, person& p, const unsigned int version)
		{
			archive& BOOST_SERIALIZATION_NVP(p.name);
			archive& BOOST_SERIALIZATION_NVP(p.age);
			archive& BOOST_SERIALIZATION_NVP(p.list);
			archive& BOOST_SERIALIZATION_NVP(p.vec);
			archive& BOOST_SERIALIZATION_NVP(p.idx2Int);
		}

	} // namespace serialization
}

int main(int argc, char* argv[])
{
	// struct to xml
	{
		std::ofstream file("archive.xml");
		boost::archive::xml_oarchive oa(file);
		person p{ "tom", 20 , {1,2,3}, {1,2,3}, { {1, 11}, {2, 21}} /*, 11*/ };
		oa& BOOST_SERIALIZATION_NVP(p);
	}
	// struct from xml
	{
		person p1;
		try
		{
			std::ifstream file("archive.xml");
			boost::archive::xml_iarchive ia(file);
			ia >> BOOST_SERIALIZATION_NVP(p1);
		}
		catch (const std::exception& e)
		{
			std::string vv = e.what();
		}
	}
	return 0;
}

boost测试代码产生的xml文件内容如下

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="19">
<p class_id="0" tracking_level="0" version="0">
	<p.name>tom</p.name>
	<p.age>20</p.age>
	<p.list>
		<count>3</count>
		<item_version>0</item_version>
		<item>1</item>
		<item>2</item>
		<item>3</item>
	</p.list>
	<p.vec>
		<count>3</count>
		<item_version>0</item_version>
		<item>1</item>
		<item>2</item>
		<item>3</item>
	</p.vec>
	<p.idx2Int class_id="3" tracking_level="0" version="0">
		<count>2</count>
		<item_version>0</item_version>
		<item class_id="4" tracking_level="0" version="0">
			<first>1</first>
			<second>11</second>
		</item>
		<item>
			<first>2</first>
			<second>21</second>
		</item>
	</p.idx2Int>
</p>
</boost_serialization>

如果xml能支持std::map就好了,这样与使用更方便,不用考虑json转xml时还要修改结构体数据类型。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants