Boost serialization and namespace - c++

I'm new using Boost serialization. I'm using xml serialization and the non intrusive version. I followed the tutorial (from Boost website) step by step and my code works fine.
The problem arise when I put my class (the code is divided in .h and .cpp plus a main.cpp file) in a namespace (ns_mytests). In this case the compiler (g++) complains and I have the following errors:
g++ -c -g test.o.d -o build/Debug/GNU-Linux-x86/sources/test.o sources/test.cpp
/opt/local/include/boost/serialization/split_free.hpp: In static member function 'static void boost::serialization::free_saver<Archive, T>::invoke(Archive&, const T&, unsigned int) [with Archive = boost::archive::xml_oarchive, T = ns_mytests::Test]':
/opt/local/include/boost/serialization/split_free.hpp:74: instantiated from 'void boost::serialization::split_free(Archive&, T&, unsigned int) [with Archive = boost::archive::xml_oarchive, T = ns_mytests::Test]'
sources/test.h:117: instantiated from 'void boost::serialization::serialize(Archive&, ns_mytests::Test&, unsigned int) [with Archive = boost::archive::xml_oarchive]'
/opt/local/include/boost/serialization/serialization.hpp:128: instantiated from 'void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::xml_oarchive, T = ns_mytests::Test]'
/opt/local/include/boost/archive/detail/oserializer.hpp:148: instantiated from 'void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::xml_oarchive, T = ns_mytests::Test]'
sources/test.cpp:146: instantiated from here
/opt/local/include/boost/serialization/split_free.hpp:45: error: no matching function for call to 'save(boost::archive::xml_oarchive&, const ns_mytests::Test&, const boost::serialization::version_type&)'
make[2]: *** [build/Debug/GNU-Linux-x86/sources/test.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
It's sure that I'm doing wrong something, but I could't find my error.
Any help is appreciated.
Thanks,
westfork

Define the non-intrusive save in the namespace where the type to be serialized is defined.

Related

serialization error when compiling with boost

I'm trying to compile a piece of software called Bagel (a quantum chemistry program, some info are here) written in C++ and which uses Boost.
I get a compilation error, and as I don't know C++ and I've never used boost I'm essentially lost. The author of the program says the problem I'm experiences depends on my boost installation and not on the program itself.
I installed boost 1.73.0 (Linux Mint 20, g++ 9.3.0) doing:
sudo ./bootstrap.sh --prefix=/usr/local
sudo ./b2 install
When compiling the program I get the following error:
/usr/local/include/boost/serialization/access.hpp:119:11: error: ‘class std::unordered_set<long unsigned int>’ has no member named ‘serialize’
119 | t.serialize(ar, file_version);
| ~~^~~~~~~~~
/usr/local/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 = std::unordered_set<long unsigned int>]’:
/usr/local/include/boost/serialization/serialization.hpp:69:22: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int)
[with Archive = boost::archive::binary_oarchive; T = std::unordered_set<long unsigned int>]’
/usr/local/include/boost/serialization/serialization.hpp:128:18: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::binary_oarchive; T = std::unordered_set<long unsigned int>]’
/usr/local/include/boost/archive/detail/oserializer.hpp:148:40: 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 = std::unordered_set<long unsigned int>]’
/usr/local/include/boost/archive/detail/oserializer.hpp:101:1: required from ‘class boost::archive::detail::oserializer<boost::archive::binary_oarchive, std::unordered_set<long unsigned int> >’
/usr/local/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 = std::unordered_set<long unsigned int>; Archive = boost::archive::binary_oarchive]’
/usr/local/include/boost/archive/detail/oserializer.hpp:308:22: [ skipping 21 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
...
The following post https://lists.boost.org/boost-users//2014/03/81583.php report on a similar error, but I don't understand what I should to solve it.
Any help would be appreciated!
Requirements say
Boost C++ Libraries - Version 1.53.0 or newer
Boost is famous of making non-backward compatible changes. 1.73 is quite distant from 1.53. I would try to install 1.53 which author of Bagel had to use and this one worked at least for him/her.

error: could not convert ‘print’ from ‘void (*)(int)’ to ‘std::function<void()>’

Following on from a previous question, I was pointed to an answer. The answer however involved a lambda function and I am trying to pass a normal function through.
Using the below code as an example:
#include <iostream>
#include <functional>
void forloop(std::function<void()> func, int arg) {
func(arg);
}
void print(int number) {
std::cout << number << std::endl;
}
int main() {
int n = 5;
forloop(print, n);
}
The following error is returned in CLion.
/home/dave/JetBrains/CLion/bin/cmake/bin/cmake --build /home/dave/CLionProjects/csv/cmake-build-debug --target csv -- -j 2
Scanning dependencies of target csv
[ 50%] Building CXX object CMakeFiles/csv.dir/main.cpp.o
/home/dave/CLionProjects/csv/main.cpp: In function ‘void forloop(std::function<void()>, int)’:
/home/dave/CLionProjects/csv/main.cpp:5:13: error: no match for call to ‘(std::function<void()>) (int&)’
func(arg);
^
In file included from /home/dave/CLionProjects/csv/main.cpp:2:0:
/usr/include/c++/6/functional:2122:5: note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {}]
function<_Res(_ArgTypes...)>::
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/6/functional:2122:5: note: candidate expects 0 arguments, 1 provided
/home/dave/CLionProjects/csv/main.cpp: In function ‘int main()’:
/home/dave/CLionProjects/csv/main.cpp:16:21: error: could not convert ‘print’ from ‘void (*)(int)’ to ‘std::function<void()>’
forloop(print, n);
^
CMakeFiles/csv.dir/build.make:62: recipe for target 'CMakeFiles/csv.dir/main.cpp.o' failed
make[3]: *** [CMakeFiles/csv.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/csv.dir/all' failed
make[2]: *** [CMakeFiles/csv.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/csv.dir/rule' failed
make[1]: *** [CMakeFiles/csv.dir/rule] Error 2
Makefile:118: recipe for target 'csv' failed
make: *** [csv] Error 2
Apologies if this questions seems silly - I am a C++ noob.
std::function<void()> means "function that returns void and takes no arguments". You're trying to pass print instead, which is a "function that returns void and takes an int". The types are mismatched.
Change forloop to:
void forloop(std::function<void(int)> func, int arg) { /* ... */ }
Also, don't use std::function to pass lambdas unless you have a good reason to do so. I suggest reading my article on the subject: "passing functions to functions".

Cassandra cpp-driver compile error

I'm trying to install Cassandra cpp-driver in Ubuntu.
I've done the steps specified in DataStax C/C++ Driver for Apache Cassandra (Beta), but i keep getting the following compile error.
[ 1%] Building CXX object CMakeFiles/cassandra.dir/src/buffer_collection.cpp.o
In file included from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/session.hpp:29:0, from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/types.hpp:22, from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/buffer_collection.cpp:19:
/root/libraries/cass_cpp-driver/git2/cpp-driver/src/logger.hpp: In member function 'int cass::Logger::init()':
/root/libraries/cass_cpp-driver/git2/cpp-driver/src/logger.hpp:40:59: error: no matching function for call to 'cass::AsyncQueue<cass::MPMCQueue<cass::Logger::LogMessage*> >::init(uv_loop_t*, cass::Logger* const, void (&)(uv_async_t*, int))'
int init() { return log_queue_.init(loop(), this, on_log); }
^
/root/libraries/cass_cpp-driver/git2/cpp-driver/src/logger.hpp:40:59: note: candidate is:
In file included from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/event_thread.hpp:21:0,
from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/session.hpp:20,
from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/types.hpp:22,
from /root/libraries/cass_cpp-driver/git2/cpp-driver/src/buffer_collection.cpp:19:
/root/libraries/cass_cpp-driver/git2/cpp-driver/src/async_queue.hpp:34:7: note: int cass::AsyncQueue<Q>::init(uv_loop_t*, void*, uv_async_cb) [with Q = cass::MPMCQueue<cass::Logger::LogMessage*>; uv_loop_t = uv_loop_s; uv_async_cb = void (*)(uv_async_s*); uv_async_t = uv_async_s] <near match>
int init(uv_loop_t* loop, void* data, uv_async_cb async_cb) {
^
/root/libraries/cass_cpp-driver/git2/cpp-driver/src/async_queue.hpp:34:7: note: no known conversion for argument 3 from 'void(uv_async_t*, int) {aka void(uv_async_s*, int)}' to 'uv_async_cb {aka void (*)(uv_async_s*)}'
make[2]: *** [CMakeFiles/cassandra.dir/src/buffer_collection.cpp.o] Error 1
make[1]: *** [CMakeFiles/cassandra.dir/all] Error 2
make: *** [all] Error 2
I've already fixed this compile errors in Cassandra cpp-driver, by down-versioning libuv to version libuv-0.10, the compile errors will be gone.
It seems that the latest updates for libuv is not yet supported by Cassandra cpp-driver.

Problems compiling Boost::Python

I want to use c++ numerical recipes on my python script but I am having some issues compiling some stuff in the Boost Python Libraries. Specificly I want to expose the amoeba function to python. I use Make rather than BJam. This is what I get when I try to compile:
costantinoagnesi#costantino-HP-Pavilion-dv5-Notebook-PC:~/Desktop/Boost Python Test$ make
g++ -I/usr/include/python2.7 -I/usr/include -fPIC -c amoeba_py.C
In file included from /usr/local/include/boost/python/object/make_instance.hpp:10:0,
from /usr/local/include/boost/python/object/make_ptr_instance.hpp:8,
from /usr/local/include/boost/python/to_python_indirect.hpp:11,
from /usr/local/include/boost/python/converter/arg_to_python.hpp:10,
from /usr/local/include/boost/python/call.hpp:15,
from /usr/local/include/boost/python/object_core.hpp:14,
from /usr/local/include/boost/python/args.hpp:25,
from /usr/local/include/boost/python.hpp:11,
from amoeba_py.C:73:
/usr/local/include/boost/python/converter/registered.hpp: In function ‘const boost::python::converter::registration&
boost::python::converter::detail::registry_lookup2(T& (*)()) [with T = double(const NRVec<double>&)]’:
/usr/local/include/boost/python/converter/registered.hpp:94:40: instantiated from ‘const >boost::python::converter::registration& boost::python::converter::detail::registry_lookup1(boost::type<T>) [with T = double (&)(const NRVec<double>&)]’
/usr/local/include/boost/python/converter/registered.hpp:105:23: instantiated from const boost::python::converter::registration& boost::python::converter::detail::registered_base<double (&)(const NRVec<double>&)>::converters’
/usr/local/include/boost/python/converter/arg_from_python.hpp:269:99: instantiated from ‘boost::python::converter::pointer_arg_from_python<T>::pointer_arg_from_python(PyObject*) [with T = double (*)(const NRVec<double>&), PyObject = _object]’
/usr/local/include/boost/python/arg_from_python.hpp:70:18: instantiated from ‘boost::python::arg_from_python<T>::arg_from_python(PyObject*) [with T = double (*)(const NRVec<double>&), PyObject = _object]’
/usr/local/include/boost/preprocessor/iteration/detail/local.hpp:43:1: instantiated from >‘PyObject* boost::python::detail::caller_arity<5u>::impl<F, Policies, Sig>::operator( (PyObject*, PyObject*) [with F = void (*)(NRMat<double>&, NRVec<double>&, double, double (*)(const NRVec<double>&), int&), Policies = boost::python::default_call_policies, Sig = boost::mpl::vector6<void, NRMat<double>&, NRVec<double>&, double, double (*)(const NRVec<double>&), int&>, PyObject = _object]’
/usr/local/include/boost/python/object/py_function.hpp:38:33: instantiated from ‘PyObject* boost::python::objects::caller_py_function_impl<Caller>::operator()(PyObject*, PyObject*) [with Caller = boost::python::detail::caller<void (*)(NRMat<double>&, NRVec<double>&, double, double (*)(const NRVec<double>&), int&), boost::python::default_call_policies, boost::mpl::vector6<void, NRMat<double>&, NRVec<double>&, double, double (*)(const NRVec<double>&), int&> >, PyObject = _object]’ amoeba_py.C:79:1: instantiated from here
/usr/local/include/boost/python/converter/registered.hpp:86:7: error: no matching function >for call to ‘register_shared_ptr1(double (*)(const NRVec<double>&))’
/usr/local/include/boost/python/converter/registered.hpp:86:7: note: candidate is:
/usr/local/include/boost/python/converter/registered.hpp:77:3: note: template<class T> void boost::python::converter::detail::register_shared_ptr1(const volatile T*)
make: *** [amoeba_py.o] Error 1
Can someone help me decipher what this error means and perhaps give me some helpful tip to finish my project. It's worth noting that the classic Boost Python example compiles just fine.
Thank you!
Here's the offending text: (lines 73-79)
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(amoeba)
{
def("amoeba", NR::amoeba);
}
I suspect you're having a similar problem to the guy who asked this question. Are you passing a function pointer as an argument in your C++ code? If so, you can't do that in Python -- see the answer as to why.
You forgot reference operator. Thus the def is getting parameter type double (*)(const NRVec<double>&) instead of const volatile T* it expects.
Your code ought to look like this:
BOOST_PYTHON_MODULE(amoeba)
{
def("amoeba", &NR::amoeba);
}

portable archive not compiling under GCC

I need to (de)serialize data on both Windows and Linux (and transfer the files in between). I wanted to use the portable binary archives of Boost's serialization library which can be found in the examples, see e.g. at http://boost-doc-zh.googlecode.com/svn-history/r380/trunk/libs/serialization/example/
This works fine on Windows (VS 2008) but fails to compile under GCC 4.3.2 with the following errors.
Can anybody suggest a solution?
Thanks a lot!
/projects/lib/BOOST/1_44_0/include/boost/archive/basic_archive.hpp: In member function 'void portable_binary_iarchive::init(unsigned int)':
/projects/lib/BOOST/1_44_0/include/boost/archive/basic_archive.hpp:78: error: 'uint_least32_t boost::archive::version_type::t' is private
/home/myfolder/src/portable_binary_iarchive.cpp:92: error: within this context
/home/myfolder/src/portable_binary_iarchive.hpp: In member function 'void portable_binary_iarchive::load(T&) [with T = boost::archive::class_id_type]':
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/iserializer.hpp:107: instantiated from 'static void boost::archive::load_access::load_primitive(Archive&, T&) [with Archive = portable_binary_iarchive, T = boost::archive::class_id_type]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/iserializer.hpp:356: instantiated from 'static void boost::archive::detail::load_non_pointer_type<Archive>::load_primitive::invoke(Archive&, T&) [with T = boost::archive::class_id_type, Archive = portable_binary_iarchive]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/iserializer.hpp:433: instantiated from 'static void boost::archive::detail::load_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = boost::archive::class_id_type, Archive = portable_binary_iarchive]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/iserializer.hpp:586: instantiated from 'void boost::archive::load(Archive&, T&) [with Archive = portable_binary_iarchive, T = boost::archive::class_id_type]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/common_iarchive.hpp:66: instantiated from 'void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = boost::archive::class_id_type, Archive = portable_binary_iarchive]'
/home/myfolder/src/portable_binary_iarchive.hpp:140: instantiated from 'void portable_binary_iarchive::load_override(T&, int) [with T = boost::archive::class_id_type]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/interface_iarchive.hpp:60: instantiated from 'Archive& boost::archive::detail::interface_iarchive<Archive>::operator>>(T&) [with T = boost::archive::class_id_type, Archive = portable_binary_iarchive]'
/projects/lib/BOOST/1_44_0/include/boost/archive/detail/common_iarchive.hpp:51: instantiated from 'void boost::archive::detail::common_iarchive<Archive>::vload(boost::archive::class_id_type&) [with Archive = portable_binary_iarchive]'
/home/myfolder/src/portable_binary_iarchive.cpp:128: instantiated from here
/home/myfolder/src/portable_binary_iarchive.hpp:107: error: call of overloaded 'class_id_type(intmax_t&)' is ambiguous
/projects/lib/BOOST/1_44_0/include/boost/archive/basic_archive.hpp:118: note: candidates are: boost::archive::class_id_type::class_id_type(size_t)
/projects/lib/BOOST/1_44_0/include/boost/archive/basic_archive.hpp:115: note: boost::archive::class_id_type::class_id_type(int)
Not really a direct answer to your question, but I've had a lot of success with Google's Protocol Buffers. They use them internally and open sourced them: http://code.google.com/p/protobuf/
I built with g++ 4.1.2 and it works fine. I hate bjam, it's hard to see what is happening, and it's unbelievably slow.
There was a warning about a deprecated header, and since this has the earmarks of a deprecated friend declaration, I was hoping to see something old, but I don't.
Did you build it with bjam or did you try to pull out the serialization into your own directory and do it yourself? Because your directory structure is not exactly like the one they have in the package.
#define private public
ought to get rid of the first error about accessing private members. It's a bit cheeky! But it can work as a temporary fix until you've understood the whole program better.