C++ Boost - 序列化错误 - 将“const B”作为“this”参数传递会丢弃限定符
Posted
技术标签:
【中文标题】C++ Boost - 序列化错误 - 将“const B”作为“this”参数传递会丢弃限定符【英文标题】:C++ Boost - serialization error - passing ‘const B’ as ‘this’ argument discards qualifiers 【发布时间】:2018-08-12 11:46:00 【问题描述】:我正在尝试使用Boost
序列化一个简单的类。我的班级只包含一个std::vector
,如下面的代码所示。我的问题是,当我按照the documentation 进行操作时,我收到了下面描述的错误。我不知道为什么,因为我没有在任何地方定义const
。你知道,我做错了什么吗?
我的代码:
#include <fstream>
#include <iostream>
#include <vector>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
class B
friend class boost::serialization::access;
private:
std::vector<int>* v;
protected:
template<class Archive>
void save(Archive & ar, const unsigned int version)
ar & this->v->size();
for(int i = 0; i < this->v->size(); i++)
ar & this->v->at(i);
;
template<class Archive>
void load(Archive & ar, const unsigned int version)
size_t size;
int tmp;
ar & size;
this->v = new std::vector<int>(size);
for(int i = 0; i < size; i++)
ar & tmp;
this->v->at(i) = tmp;
BOOST_SERIALIZATION_SPLIT_MEMBER()
public:
B();
B(std::vector<int>* v);
void print_vals();
;
B::B()
this->v = nullptr;
B::B(std::vector<int>* v)
this->v = v;
void B::print_vals()
for(auto e : *(this->v))
std::cout << e << std::endl;
int main()
std::vector<int> v1,2,3;
B b(&v);
std::ofstream ofs("b.txt");
boost::archive::text_oarchive oa(ofs);
oa << b;
ofs.close();
错误
In file included from /usr/include/boost/serialization/extended_type_info_typeid.hpp:37,
from /usr/include/boost/archive/detail/oserializer.hpp:39,
from /usr/include/boost/archive/detail/interface_oarchive.hpp:23,
from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
from /usr/include/boost/archive/basic_text_oarchive.hpp:29,
from /usr/include/boost/archive/text_oarchive.hpp:31,
from /home/martin/CLionProjects/boost_serialization_example/main.cpp:4:
/usr/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::member_save(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = const B]’:
/usr/include/boost/serialization/split_member.hpp:43:32: required from ‘static void boost::serialization::detail::member_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = B]’
/usr/include/boost/serialization/split_member.hpp:69:18: required from ‘void boost::serialization::split_member(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = B]’
/home/martin/CLionProjects/boost_serialization_example/main.cpp:35:5: required from ‘void B::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive]’
/usr/include/boost/serialization/access.hpp:116:9: required from ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = B]’
/usr/include/boost/serialization/serialization.hpp:68:22: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = B]’
/usr/include/boost/serialization/serialization.hpp:126:14: [ skipping 4 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/oserializer.hpp:310:22: required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, const T&) [with T = B; Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:534:18: required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::text_oarchive; T = const B]’
/usr/include/boost/archive/detail/common_oarchive.hpp:70:22: required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&) [with T = const B; Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/basic_text_oarchive.hpp:83:9: required from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&) [with T = const B; Archive = boost::archive::text_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:70:9: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(const T&) [with T = B; Archive = boost::archive::text_oarchive]’
/home/martin/CLionProjects/boost_serialization_example/main.cpp:107:15: required from here
/usr/include/boost/serialization/access.hpp:91:9: error: passing ‘const B’ as ‘this’ argument discards qualifiers [-fpermissive]
t.save(ar, file_version);
编辑 1:
我已经根据答案重写了我的save
和load
函数,但错误仍然存在......
template<class Archive>
void save(Archive & ar, const unsigned int version)
ar & this->v->size();
for(int i = 0; i < this->v->size(); i++)
ar & (*this->v)[i];
;
template<class Archive>
void load(Archive & ar, const unsigned int version)
size_t size;
int tmp;
ar & size;
this->v = new std::vector<int>(size);
for(int i = 0; i < size; i++)
ar & tmp;
(*this->v)[i] = tmp;
【问题讨论】:
【参考方案1】:解决办法:
您的save()
方法需要像这样声明const
:
void save(Archive & ar, const unsigned int version) const
...
这将使它编译没有错误。如果您还想要完整的无警告编译,那么还要将save()
内的for
循环修复为这样(将i
的类型从int
更改为size_t
):
for (size_t i = 0; i < this->v->size(); i++)
说明:
我不知道为什么,因为我没有在任何地方定义 const。你知道吗, 我做错了什么?
所以问题不在于您没有定义 const,而是您定义的不够。看,当你打电话时
oa << b;
那么boost::archive::text_oarchive
类的运算符<<
的实例化版本具有以下签名:
'Archive &boost::archive::detail::interface_oarchive<Archive>::operator <<<B>(const T &)'
因此,它期望获得const T&
。但是,它会满足于常规的T&
,因为当期望const
参数时,非const
被接受。但是随后它尝试将其用作 const 无济于事,因为它调用的方法根本没有定义const
,因此您值得信赖的编译器足够明智地立即阻止您:)
【讨论】:
谢谢!但我想,只有save
方法应该是const
,因为load
是const
使得无法初始化正在加载的对象的属性。
@Eenoku 当然 100%,批准并更正。我思绪飘忽,匆匆写下。我很抱歉。无论如何,现在答案是完整的。希望它有所帮助。以上是关于C++ Boost - 序列化错误 - 将“const B”作为“this”参数传递会丢弃限定符的主要内容,如果未能解决你的问题,请参考以下文章
Boost mpl::list 变体序列化 check_const_loading() 编译错误
如何使用 boost_python 将 C++ 序列化数据公开给 python
如何将序列化方法添加到作为 Windows 数据结构的类成员,以便在 C++ 中与 boost 序列化一起使用