我目前正在使用c ++ boost库来保存来自实时控制系统(OS:Linux)的一些数据。我要保存的数据是通过以下方式定义的对象:
#ifndef RECDATA_HPP
#define RECDATA_HPP
#include <vector>
template<class T>
class RecData
{
private:
std::vector<std::vector<T>> data;
std::vector<unsigned long> time;
// Allow serialization to access non-public data members.
friend class boost::serialization::access;
// Implement serialize method
template <class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & data;
ar & time;
}
public:
std::vector<std::vector<T>> getData(){
return this->data;
}
std::vector<unsigned long> getTime(){
return this->time;
}
void PushData(std::vector<T> inData);
void PushTime(unsigned long curTime);
};
template<class T>
void RecData<T>::PushData(std::vector<T> inData){
this->data.push_back(inData);
}
template<class T>
void RecData<T>::PushTime(unsigned long curTime){
this->time.push_back(curTime);
}
#endif //RECDATA_HPP
当我直接将其保存在main中时,此方法很好用,例如:
#include <fstream>
#include <iostream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include "vect_container.hpp"
#include "Recorder.hpp"
#include "RecData.hpp"
int main()
{
RecData<int> *recData1 = new RecData<int>();
for(int i=0;i<5;i++){
std::vector<int> temp;
for(int k=0;k<10;k++){
temp.push_back(i+k);
}
recData1->PushData(temp);
recData1->PushTime((unsigned long)i);
}
{
std::ofstream ofs("temp.dat");
boost::archive::text_oarchive ar(ofs);
ar & *recData1;
delete recData1;
}
RecData<int> restore = RecData<int>();
{
std::ifstream ifs("temp.dat");
boost::archive::text_iarchive ar(ifs);
ar &restore;
}
std::vector<unsigned long> timeGet = restore.getTime();
std::vector<std::vector<int>> dataGet = restore.getData();
for(int i=0;i<5;i++){
std::cout<<timeGet[i]<<std::endl;
for(int k=0;k<10;k++){
std::cout<<dataGet[i][k];
}
std::cout<<std::endl;
}
}
但是,如果现在我在对象中调用此方法,它将无法编译。
template<class T>
void Recorder::writeTemp(RecData<T> *tempData, int recType)
{
{
std::ofstream ofs(this->fileName);
boost::archive::text_oarchive ar(ofs);
ar & *tempData;
delete tempData;
}
}
编译器不断告诉我:
error: ‘class std::vector<std::vector<int>, std::allocator<std::vector<int> > >’ has no member named ‘serialize’
或
error: ‘class std::vector<std::vector<int>, std::allocator<std::vector<int> > >’ has no member named ‘serialize’
但是,我相信我已经在RecData类中明确定义了序列化,并且当我在main中序列化此类对象时它起作用了。我想知道这个问题的原因是什么。
答案 0 :(得分:4)
我编辑了您的片段,以产生以下最小的可重现示例:
#include <vector>
#include <fstream>
#include <iostream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
//Comment below line, get same error
#include <boost/serialization/vector.hpp>
template<class T>
class RecData
{
private:
std::vector<std::vector<T>> data;
std::vector<unsigned long> time;
// Allow serialization to access non-public data members.
friend class boost::serialization::access;
// Implement serialize method
template <class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar& data;
ar& time;
}
public:
std::vector<std::vector<T>> getData() {
return this->data;
}
std::vector<unsigned long> getTime() {
return this->time;
}
void PushData(std::vector<T> inData);
void PushTime(unsigned long curTime);
};
template<class T>
void RecData<T>::PushData(std::vector<T> inData) {
this->data.push_back(inData);
}
template<class T>
void RecData<T>::PushTime(unsigned long curTime) {
this->time.push_back(curTime);
}
int main()
{
RecData<int>* recData1 = new RecData<int>();
for (int i = 0; i < 5; i++) {
std::vector<int> temp;
for (int k = 0; k < 10; k++) {
temp.push_back(i + k);
}
recData1->PushData(temp);
recData1->PushTime((unsigned long)i);
}
{
std::ofstream ofs("temp.dat");
boost::archive::text_oarchive ar(ofs);
ar&* recData1;
delete recData1;
}
}
如果我注释掉
#include <boost/serialization/vector.hpp>
我得到的错误与您一样,
Error C2039 'serialize': is not a member of 'std::vector<std::vector<T,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allo>cator<_Ty>>>>'
Error C2039 'serialize': is not a member of 'std::vector<unsigned long,std::allocator<_Ty>>'
如果我保留这一行,它将进行编译。
因此,我认为从某种程度上来说,您的主要内容是间接包括上述标题,而您定义函数的文件则没有。
尝试在定义RecData
的标头中也将标头也包含在定义函数的文件中。我认为,鉴于成功使用该类需要该文件,因此它应该放在RecData
的标头中,但是选择取决于您。
在Microsoft Visual Studio 2019中测试,Boost 1.70.0