提升序列化犰狳矩阵
Boost serializing armadillo matrices
我试图确保序列化适用于矩阵,即犰狳,但我遇到了一些错误。
我制作了一个简单的随机矩阵示例,并尝试使用 boost 将内容保存在二进制文件中,然后使用 boost 加载它:
#include <iostream>
#include <fstream>
#include <boost/archive/tmpdir.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
int main() {
arma::mat A = arma::randu<arma::mat>(4,5);
std::ofstream outputStream;
outputStream.open("bin.dat");
std::ostringstream oss;
boost::archive::binary_oarchive oa(outputStream);
oa & A;
outputStream.close(); getting error
arma::mat B;
std::ifstream inputStream;
inputStream.open("bin.dat", std::ifstream::in);
boost::archive::binary_iarchive ia(inputStream);
ia & B;
return 0;
}
我收到以下错误(当 运行 命令时:g++ -std=c++11 arma_boost.cpp -larmadillo -lboost_serialization
):
In file included from /usr/include/boost/serialization/split_member.hpp:23:0,
from /usr/include/boost/serialization/nvp.hpp:33,
from /usr/include/boost/serialization/array.hpp:19,
from /usr/include/boost/archive/basic_binary_oprimitive.hpp:50,
from /usr/include/boost/archive/binary_oarchive_impl.hpp:22,
from /usr/include/boost/archive/binary_oarchive.hpp:21,
from arma_boost.cpp:4:
/usr/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’:
/usr/include/boost/serialization/serialization.hpp:69:69: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/serialization/serialization.hpp:128:27: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/oserializer.hpp:152:5: required from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/oserializer.hpp:101:1: required from ‘class boost::archive::detail::oserializer<boost::archive::binary_oarchive, arma::Mat<double> >’
/usr/include/boost/archive/detail/oserializer.hpp:253:13: required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::save_standard::invoke(Archive&, const T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:308:28: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_oarchive.hpp:69:40: required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/basic_binary_oarchive.hpp:75:7: required from ‘void boost::archive::basic_binary_oarchive<Archive>::save_override(const T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/binary_oarchive_impl.hpp:51:9: required from ‘void boost::archive::binary_oarchive_impl<Archive, Elem, Tr>::save_override(T&, int) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:63:9: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:71:35: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
arma_boost.cpp:19:6: required from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class arma::Mat<double>’ has no member named ‘serialize’
t.serialize(ar, file_version);
^
/usr/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’:
/usr/include/boost/serialization/serialization.hpp:69:69: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/serialization/serialization.hpp:128:27: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/iserializer.hpp:192:5: required from ‘void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/iserializer.hpp:120:1: required from ‘class boost::archive::detail::iserializer<boost::archive::binary_iarchive, arma::Mat<double> >’
/usr/include/boost/archive/detail/iserializer.hpp:387:13: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::load_standard::invoke(Archive&, const T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:439:28: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:26:6: required from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class arma::Mat<double>’ has no member named ‘serialize’
编辑:
#include <iostream>
#include <fstream>
#include <boost/archive/tmpdir.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, arma::mat &m, const unsigned int version)
{
ar & m.n_cols;
ar & m.n_rows;
ar & m.n_elem;
}
}
}
int main() {
arma::mat A = arma::randu<arma::mat>(4,5);
std::ofstream outputStream;
outputStream.open("bin.dat");
std::ostringstream oss;
boost::archive::binary_oarchive oa(outputStream);
oa & A;
outputStream.close();
arma::mat b; //tried also arma::mat b(4,5);
std::ifstream inputStream;
inputStream.open("bin.dat", std::ifstream::in);
boost::archive::binary_iarchive ia(inputStream);
ia & b;
return 0;
}
这些是我收到的错误:
In file included from /usr/include/boost/archive/basic_text_oprimitive.hpp:34:0,
from /usr/include/boost/archive/text_oarchive.hpp:30,
from arma_boost.cpp:3:
/usr/include/boost/archive/detail/check.hpp: In instantiation of ‘void boost::archive::detail::check_const_loading() [with T = const unsigned int]’:
/usr/include/boost/archive/detail/iserializer.hpp:577:38: required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:54:8: required from here
/usr/include/boost/archive/detail/check.hpp:162:5: error: static assertion failed: typex::value
BOOST_STATIC_ASSERT(typex::value);
^
In file included from /usr/include/boost/archive/binary_iarchive_impl.hpp:21:0,
from /usr/include/boost/archive/binary_iarchive.hpp:20,
from arma_boost.cpp:11:
/usr/include/boost/archive/basic_binary_iprimitive.hpp: In instantiation of ‘void boost::archive::basic_binary_iprimitive<Archive, Elem, Tr>::load(T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’:
/usr/include/boost/archive/detail/iserializer.hpp:107:9: required from ‘static void boost::archive::load_access::load_primitive(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/iserializer.hpp:362:46: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::load_primitive::invoke(Archive&, T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:439:28: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:592:24: required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: [ skipping 11 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:54:8: required from here
/usr/include/boost/archive/basic_binary_iprimitive.hpp:88:35: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
load_binary(& t, sizeof(T));
^
/usr/include/boost/archive/basic_binary_iprimitive.hpp:149:1: note: initializing argument 1 of ‘void boost::archive::basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(void*, std::size_t) [with Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>; std::size_t = long unsigned int]’
basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
^
犰狳提供了一种将其类型保存到 HDF5 文件的方法,该方法运行良好并且可能对您来说已经足够了。
犰狳不支持提升序列化。从boost serialization tutorial我们可以看出,一个class必须有一个serialize
方法才能用boost序列化。犰狳没有这样的方法,这就是你得到的错误。
或者,boost 还允许以非侵入方式使 class 使用它,这涉及实现 serialize
自由函数。由于您所需要的只是矩阵中的元素及其维度,因此在提升 serialization tutorial.
之后应该很容易实现
编辑完问题再编辑。
你得到的错误一开始确实很难查明原因,但如果你注释加载部分的行(return 之前的最后一行)你会发现它编译得很好。如果你 运行 可执行文件,二进制文件将被创建,因此序列化部分正在工作(但请记住你问题中的序列化函数尚未序列化元素)。
现在让我们回到错误
/usr/include/boost/archive/basic_binary_iprimitive.hpp:88:35: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
load_binary(& t, sizeof(T));
有一些 const 类型(被 boost 擦除,因此你得到 void *)不应该是 const。如果我们再看一下 serialize template 函数和教程,我们可以看到它同时用于序列化和加载,尽管在每种情况下 Archive
类型不同。这意味着在下面的代码中
ar & m.n_cols;
ar & m.n_rows;
ar & m.n_elem;
在序列化过程中,值是从 m
中读取的(确定)。然而,在加载期间,值被写入 m
,这是不正确的,因为这些是常量属性。那就是问题所在。为了解决这个问题,您需要将保存和加载拆分为单独的函数。然后,在 load
实现中,您可以使用其中一个犰狳构造函数从加载的数据创建一个新矩阵。最简单的方法是删除模板并为序列化函数创建两个重载
// This is the saving part
void serialize(boost::archive::binary_oarchive &ar, arma::mat &m,
const unsigned int version) {
ar &m.n_cols;
ar &m.n_rows;
ar &m.n_elem; // You don't really need this one
// Note: You must also serialize the elements, which is currently missing
}
// This is the loading part
void serialize(boost::archive::binary_iarchive &ar, arma::mat &m,
const unsigned int version) {
// use one of the suitable constructors here
m = arma::mat( ... )
}
两个序列化重载的可能完整实现如下所示(我通过打印 A
和 B
矩阵测试了它们,它们是相同的)。最重要的是要记住,您必须按照保存值的相同顺序读取值。
void serialize(boost::archive::binary_oarchive &ar, arma::mat &m,
const unsigned int version) {
// Since this is used only for reading I prefer the "<<" symbol instead of
// "&", but "&" would work just fine
ar << m.n_cols;
ar << m.n_rows;
// Loop to save each element in order
for (unsigned i = 0; i < m.n_elem; i++) {
// memptr gives us a pointer to the raw memory used to store the elements
ar << m.memptr()[i];
}
}
void serialize(boost::archive::binary_iarchive &ar, arma::mat &m,
const unsigned int version) {
arma::uword n_cols;
arma::uword n_rows;
ar >> n_cols;
ar >> n_rows;
m = arma::mat(n_rows, n_cols);
// Loop to read each element in order
for (unsigned i = 0; i < m.n_elem; i++) {
ar >> m.memptr()[i];
}
}
免责声明:实际上我以前从未使用过 boost 序列化,因此可能有更好的方法来做到这一点。
我试图确保序列化适用于矩阵,即犰狳,但我遇到了一些错误。
我制作了一个简单的随机矩阵示例,并尝试使用 boost 将内容保存在二进制文件中,然后使用 boost 加载它:
#include <iostream>
#include <fstream>
#include <boost/archive/tmpdir.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
int main() {
arma::mat A = arma::randu<arma::mat>(4,5);
std::ofstream outputStream;
outputStream.open("bin.dat");
std::ostringstream oss;
boost::archive::binary_oarchive oa(outputStream);
oa & A;
outputStream.close(); getting error
arma::mat B;
std::ifstream inputStream;
inputStream.open("bin.dat", std::ifstream::in);
boost::archive::binary_iarchive ia(inputStream);
ia & B;
return 0;
}
我收到以下错误(当 运行 命令时:g++ -std=c++11 arma_boost.cpp -larmadillo -lboost_serialization
):
In file included from /usr/include/boost/serialization/split_member.hpp:23:0,
from /usr/include/boost/serialization/nvp.hpp:33,
from /usr/include/boost/serialization/array.hpp:19,
from /usr/include/boost/archive/basic_binary_oprimitive.hpp:50,
from /usr/include/boost/archive/binary_oarchive_impl.hpp:22,
from /usr/include/boost/archive/binary_oarchive.hpp:21,
from arma_boost.cpp:4:
/usr/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’:
/usr/include/boost/serialization/serialization.hpp:69:69: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/serialization/serialization.hpp:128:27: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/oserializer.hpp:152:5: required from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::binary_oarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/oserializer.hpp:101:1: required from ‘class boost::archive::detail::oserializer<boost::archive::binary_oarchive, arma::Mat<double> >’
/usr/include/boost/archive/detail/oserializer.hpp:253:13: required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::save_standard::invoke(Archive&, const T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/detail/oserializer.hpp:308:28: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_oarchive.hpp:69:40: required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/basic_binary_oarchive.hpp:75:7: required from ‘void boost::archive::basic_binary_oarchive<Archive>::save_override(const T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/binary_oarchive_impl.hpp:51:9: required from ‘void boost::archive::binary_oarchive_impl<Archive, Elem, Tr>::save_override(T&, int) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:63:9: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = const arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
/usr/include/boost/archive/detail/interface_oarchive.hpp:71:35: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_oarchive]’
arma_boost.cpp:19:6: required from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class arma::Mat<double>’ has no member named ‘serialize’
t.serialize(ar, file_version);
^
/usr/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’:
/usr/include/boost/serialization/serialization.hpp:69:69: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/serialization/serialization.hpp:128:27: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/iserializer.hpp:192:5: required from ‘void boost::archive::detail::iserializer<Archive, T>::load_object_data(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::binary_iarchive; T = arma::Mat<double>]’
/usr/include/boost/archive/detail/iserializer.hpp:120:1: required from ‘class boost::archive::detail::iserializer<boost::archive::binary_iarchive, arma::Mat<double> >’
/usr/include/boost/archive/detail/iserializer.hpp:387:13: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::load_standard::invoke(Archive&, const T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:439:28: [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:26:6: required from here
/usr/include/boost/serialization/access.hpp:118:9: error: ‘class arma::Mat<double>’ has no member named ‘serialize’
编辑:
#include <iostream>
#include <fstream>
#include <boost/archive/tmpdir.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <armadillo>
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, arma::mat &m, const unsigned int version)
{
ar & m.n_cols;
ar & m.n_rows;
ar & m.n_elem;
}
}
}
int main() {
arma::mat A = arma::randu<arma::mat>(4,5);
std::ofstream outputStream;
outputStream.open("bin.dat");
std::ostringstream oss;
boost::archive::binary_oarchive oa(outputStream);
oa & A;
outputStream.close();
arma::mat b; //tried also arma::mat b(4,5);
std::ifstream inputStream;
inputStream.open("bin.dat", std::ifstream::in);
boost::archive::binary_iarchive ia(inputStream);
ia & b;
return 0;
}
这些是我收到的错误:
In file included from /usr/include/boost/archive/basic_text_oprimitive.hpp:34:0,
from /usr/include/boost/archive/text_oarchive.hpp:30,
from arma_boost.cpp:3:
/usr/include/boost/archive/detail/check.hpp: In instantiation of ‘void boost::archive::detail::check_const_loading() [with T = const unsigned int]’:
/usr/include/boost/archive/detail/iserializer.hpp:577:38: required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:54:8: required from here
/usr/include/boost/archive/detail/check.hpp:162:5: error: static assertion failed: typex::value
BOOST_STATIC_ASSERT(typex::value);
^
In file included from /usr/include/boost/archive/binary_iarchive_impl.hpp:21:0,
from /usr/include/boost/archive/binary_iarchive.hpp:20,
from arma_boost.cpp:11:
/usr/include/boost/archive/basic_binary_iprimitive.hpp: In instantiation of ‘void boost::archive::basic_binary_iprimitive<Archive, Elem, Tr>::load(T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’:
/usr/include/boost/archive/detail/iserializer.hpp:107:9: required from ‘static void boost::archive::load_access::load_primitive(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/iserializer.hpp:362:46: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::load_primitive::invoke(Archive&, T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:439:28: required from ‘static void boost::archive::detail::load_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/iserializer.hpp:592:24: required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = const unsigned int]’
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = const unsigned int; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: [ skipping 11 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/common_iarchive.hpp:66:40: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:70:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:50:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:60:9: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/detail/interface_iarchive.hpp:67:32: required from ‘Archive& boost::archive::detail::interface_iarchive<Archive>::operator&(T&) [with T = arma::Mat<double>; Archive = boost::archive::binary_iarchive]’
arma_boost.cpp:54:8: required from here
/usr/include/boost/archive/basic_binary_iprimitive.hpp:88:35: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
load_binary(& t, sizeof(T));
^
/usr/include/boost/archive/basic_binary_iprimitive.hpp:149:1: note: initializing argument 1 of ‘void boost::archive::basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(void*, std::size_t) [with Archive = boost::archive::binary_iarchive; Elem = char; Tr = std::char_traits<char>; std::size_t = long unsigned int]’
basic_binary_iprimitive<Archive, Elem, Tr>::load_binary(
^
犰狳提供了一种将其类型保存到 HDF5 文件的方法,该方法运行良好并且可能对您来说已经足够了。
犰狳不支持提升序列化。从boost serialization tutorial我们可以看出,一个class必须有一个serialize
方法才能用boost序列化。犰狳没有这样的方法,这就是你得到的错误。
或者,boost 还允许以非侵入方式使 class 使用它,这涉及实现 serialize
自由函数。由于您所需要的只是矩阵中的元素及其维度,因此在提升 serialization tutorial.
编辑完问题再编辑。
你得到的错误一开始确实很难查明原因,但如果你注释加载部分的行(return 之前的最后一行)你会发现它编译得很好。如果你 运行 可执行文件,二进制文件将被创建,因此序列化部分正在工作(但请记住你问题中的序列化函数尚未序列化元素)。
现在让我们回到错误
/usr/include/boost/archive/basic_binary_iprimitive.hpp:88:35: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
load_binary(& t, sizeof(T));
有一些 const 类型(被 boost 擦除,因此你得到 void *)不应该是 const。如果我们再看一下 serialize template 函数和教程,我们可以看到它同时用于序列化和加载,尽管在每种情况下 Archive
类型不同。这意味着在下面的代码中
ar & m.n_cols;
ar & m.n_rows;
ar & m.n_elem;
在序列化过程中,值是从 m
中读取的(确定)。然而,在加载期间,值被写入 m
,这是不正确的,因为这些是常量属性。那就是问题所在。为了解决这个问题,您需要将保存和加载拆分为单独的函数。然后,在 load
实现中,您可以使用其中一个犰狳构造函数从加载的数据创建一个新矩阵。最简单的方法是删除模板并为序列化函数创建两个重载
// This is the saving part
void serialize(boost::archive::binary_oarchive &ar, arma::mat &m,
const unsigned int version) {
ar &m.n_cols;
ar &m.n_rows;
ar &m.n_elem; // You don't really need this one
// Note: You must also serialize the elements, which is currently missing
}
// This is the loading part
void serialize(boost::archive::binary_iarchive &ar, arma::mat &m,
const unsigned int version) {
// use one of the suitable constructors here
m = arma::mat( ... )
}
两个序列化重载的可能完整实现如下所示(我通过打印 A
和 B
矩阵测试了它们,它们是相同的)。最重要的是要记住,您必须按照保存值的相同顺序读取值。
void serialize(boost::archive::binary_oarchive &ar, arma::mat &m,
const unsigned int version) {
// Since this is used only for reading I prefer the "<<" symbol instead of
// "&", but "&" would work just fine
ar << m.n_cols;
ar << m.n_rows;
// Loop to save each element in order
for (unsigned i = 0; i < m.n_elem; i++) {
// memptr gives us a pointer to the raw memory used to store the elements
ar << m.memptr()[i];
}
}
void serialize(boost::archive::binary_iarchive &ar, arma::mat &m,
const unsigned int version) {
arma::uword n_cols;
arma::uword n_rows;
ar >> n_cols;
ar >> n_rows;
m = arma::mat(n_rows, n_cols);
// Loop to read each element in order
for (unsigned i = 0; i < m.n_elem; i++) {
ar >> m.memptr()[i];
}
}
免责声明:实际上我以前从未使用过 boost 序列化,因此可能有更好的方法来做到这一点。