이전 아카이브와의 호환성을 유지하면서 직렬화 된 멤버 유형을 어떻게 처리합니까? 예 : float/int
을 double/size_t
으로 변경하고 싶습니다.부스트 클래스 직렬화, 멤버 유형 변경
버전 번호를 늘릴 수는 있지만 코드가 지저분 해집니다. 그것을 처리 할 수있는 다른 방법이 있습니까? 차이가 나는 경우 멤버는 MAKE_NVP
을 통해 일련 번호가 지정됩니다.
이전 아카이브와의 호환성을 유지하면서 직렬화 된 멤버 유형을 어떻게 처리합니까? 예 : float/int
을 double/size_t
으로 변경하고 싶습니다.부스트 클래스 직렬화, 멤버 유형 변경
버전 번호를 늘릴 수는 있지만 코드가 지저분 해집니다. 그것을 처리 할 수있는 다른 방법이 있습니까? 차이가 나는 경우 멤버는 MAKE_NVP
을 통해 일련 번호가 지정됩니다.
version
매개 변수를 버전에 사용할 수 있습니다. 설명서는 다음 예제를 제공합니다. http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/tutorial.html#versioning
BOOST_CLASS_VERSION
매크로로 직렬화 버전을 지정하는 방법에 유의하십시오. 여기
struct DataV0
{
float f = 3.14;
int i = 42;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
if (0 != version)
throw std::runtime_error("Unsupported version");
ar & f;
ar & i;
}
};
지금, 당신의 V1 직렬화 형식으로, 당신은 당신의 문제로 유형을 변경 :
struct DataV1
{
double d = 3.14;
size_t ul = 42;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
switch(version)
{
case 0:
{
DataV0 old;
ar & old.f;
ar & old.i;
d = old.f;
assert(old.i >= std::numeric_limits<size_t>::min());
assert(old.i <= std::numeric_limits<size_t>::max());
ul = static_cast<size_t>(old.i);
}
break;
case 1:
ar & d;
ar & ul;
break;
}
}
};
BOOST_CLASS_VERSION(DataV1, 1)
전체 테스트 프로그램 :
template <typename Data>
std::string to_string(Data d)
{
std::ostringstream oss;
boost::archive::text_oarchive oa(oss);
oa << d;
return oss.str();
}
template <typename Data>
bool verify(std::string const& text)
{
std::istringstream iss(text);
boost::archive::text_iarchive ia(iss);
Data d;
ia >> d;
return text == to_string(d);
}
int main()
{
std::string v0text = to_string(DataV0());
std::string v1text = to_string(DataV1());
std::cout << v0text << '\n';
std::cout << v1text << '\n';
std::cout << "v0 as v0: " << std::boolalpha << verify<DataV0>(v0text) << "\n";
std::cout << "v0 as v1: " << std::boolalpha << verify<DataV1>(v0text) << "\n";
std::cout << "v1 as v1: " << std::boolalpha << verify<DataV1>(v1text) << "\n";
try {
std::cout << "v1 as v0: " << std::boolalpha << verify<DataV0>(v1text) << "\n";
} catch (std::exception const& e)
{
std::cerr << "Threw the expected '" << e.what() << "'\n";
}
}
지문 :
22 serialization::archive 10 0 0 3.1400001 42
22 serialization::archive 10 0 1 3.1400000000000001 42
v0 as v0: true
v0 as v1: false
v1 as v1: true
v1 as v0: Threw the expected 'Unsupported version'
구조체가 다른 클래스의 개인/보호 된 멤버 인 경우 위의 대답을 확장하기 만하면 매크로를 사용하여 버전을 지정할 수도 있지만 클래스 범위를 사용하여 버전을 지정할 수 있습니다 :'BOOST_CLASS_VERSION (MyClass, 1); BOOST_CLASS_VERSION (MyClass :: MyPrivateStruct, 2);' – Colin
이름 - 값 쌍은 차이가 없습니다. – sehe