我正在追逐一只兔子,试图找出以下内容:
缩小的例子如下所示:
template <class s_trait>
class state
{
public:
state(s_trait);
private:
state() = default;
friend class boost::serialization::access;
template <typename archive>
void serialize(archive &, const unsigned int);
};
template <class a_trait>
class action
{
public:
action(a_trait);
private:
action() = default;
friend class boost::serialization::access;
template <typename archive>
void serialize(archive &, const unsigned int);
};
template <class state_type, class action_type>
class policy
{
public:
/// ... some public methods
private:
friend class boost::serialization::access;
std::unordered_map<state_class,
std::unordered_map<action_class,
double>> __policies__;
template <typename archive>
void serialize(archive &, const unsigned int);
};
上述骨架(没有枯燥的细节)有以下设计问题:
state
无法识别操作
action
无法了解state
,反之亦然policy
模板state
和action
有意然而,使用这些类编译应用程序会产生std :: pair引起的问题,这似乎源于boost :: serialization :: access,而这似乎来自于类policy
需要的事实调用serialize
时访问默认的空构造函数:
/usr/include/c++/5/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<_T1, _T2>::pair() [with _T1 = const relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >; _T2 = std::unordered_map<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mu
mbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double> > >]’:
/usr/include/boost/serialization/access.hpp:132:9: required from ‘static void boost::serialization::access::construct(T*) [with T = std::pair<const relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, std::unordered_map<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, rel
earn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double> > > >]’
/usr/include/boost/serialization/serialization.hpp:93:22: required from ‘void boost::serialization::load_construct_data(Archive&, T*, unsigned int) [with Archive = boost::archive::binary_iarchive; T = std::pair<const relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, std::unordered_map<relearn::act
ion<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::action<mumbler::action<std::__cxx11::b
asic_string<char> > >, double> > > >]’
/usr/include/boost/serialization/serialization.hpp:158:28: required from ‘void boost::serialization::load_construct_data_adl(Archive&, T*, unsigned int) [with Archive = boost::archive::binary_iarchive; T = std::pair<const relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, std::unordered_map<relearn
::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::action<mumbler::action<std::__cxx
11::basic_string<char> > >, double> > > >]’
/usr/include/boost/serialization/detail/stack_constructor.hpp:54:54: required from ‘boost::serialization::detail::stack_construct<Archive, T>::stack_construct(Archive&, unsigned int) [with Archive = boost::archive::binary_iarchive; T = std::pair<const relearn::state<mumbler::state<std::__cxx11::basic_string<char> >
>, std::unordered_map<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::act
ion<mumbler::action<std::__cxx11::basic_string<char> > >, double> > > >]’
/usr/include/boost/serialization/unordered_map.hpp:45:55: required from ‘void boost::serialization::stl::archive_input_unordered_map<Archive, Container>::operator()(Archive&, Container&, unsigned int) [with Archive = boost::archive::binary_iarchive; Container = std::unordered_map<relearn::state<mumbler::state<std::
__cxx11::basic_string<char> > >, std::unordered_map<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::allocator
<std::pair<const relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double> > >, relearn::hasher<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > > >, std::allocator<std::pair<const relearn::state<mu
mbler::state<std::__cxx11::basic_string<char> > >, std::unordered_map<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double, relearn::hasher<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >, std::equal_to<relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >
>, std::allocator<std::pair<const relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >, double> > > > > >]’
/usr/include/boost/serialization/unordered_collections_load_imp.hpp:66:14: [ skipping 24 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/boost/archive/detail/iserializer.hpp:618:18: required from ‘void boost::archive::load(Archive&, T&) [with Archive = boost::archive::binary_iarchive; T = relearn::policy<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, relearn::action<mumbler::action<std::__cxx11::basic_string<char> >
> >]’
/usr/include/boost/archive/detail/common_iarchive.hpp:66:22: required from ‘void boost::archive::detail::common_iarchive<Archive>::load_override(T&, int) [with T = relearn::policy<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, relearn::action<mumbler::action<std::__cxx11::basic_string<char> > >
>; Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/basic_binary_iarchive.hpp:76:7: required from ‘void boost::archive::basic_binary_iarchive<Archive>::load_override(T&, int) [with T = relearn::policy<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, relearn::action<mumbler::action<std::__cxx11::basic_string<char> > > >;
Archive = boost::archive::binary_iarchive]’
/usr/include/boost/archive/binary_iarchive_impl.hpp:62:9: required from ‘void boost::archive::binary_iarchive_impl<Archive, Elem, Tr>::load_override(T&, int) [with T = relearn::policy<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, relearn::action<mumbler::action<std::__cxx11::basic_string<char>
> > >; 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 = relearn::policy<relearn::state<mumbler::state<std::__cxx11::basic_string<char> > >, relearn::action<mumbler::action<std::__cxx11::basic_string<char> >
> >; Archive = boost::archive::binary_iarchive]’
/home/alex/codez/mumbler/src/agent.cpp:9:11: required from here
/home/alex/codez/mumbler/src/relearn/src/relearn.hpp:90:5: error: ‘relearn::state<state_trait, value_type>::state() [with state_trait = mumbler::state<std::__cxx11::basic_string<char> >; value_type = double]’ is private
state() = default;
据我所见,我有两个选择:
有没有其他方法可以解决这个问题而不暴露公共空构造函数?
这不是重复,我知道如何(de)序列化,问题是隐藏默认构造函数,只有(de)序列化程序可以访问它。
答案 0 :(得分:2)
创建默认构造函数protected
,然后从具有公共构造函数的每个构造函数创建一个派生类,但完全从外部隐藏这些派生类(将它们放在detail
头文件中,其他人不包含)。然后你的policy
类可以在内部使用派生类,用于序列化和存储,但只将它们公开为(切片的)基类对象。