gpt4 book ai didi

c++ - 序列化所需的公共(public)空构造函数

转载 作者:行者123 更新时间:2023-11-30 03:30:39 25 4
gpt4 key购买 nike

我正在追逐一只兔子,试图弄清楚以下内容:

  1. 我不想要空的公共(public)构造函数(它们可以而且会产生问题)
  2. 两个模板类必须互不相识,否则会出现模板参数循环问题
  3. 第三类显然需要访问之前的两个类,因为它是正在被(反)序列化的类

一个缩小的例子如下所示:

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);
};

上面的骨架(没有无聊的细节)有以下设计问题:

  • class state不能感知 Action ,如果 Action 是感知状态的话
  • class action 无法感知state,反之亦然
  • class policy 有目的地模板化stateaction

但是,使用这些类编译应用程序会产生由 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;

据我所知,我有两个选择:

  1. 保留一个公共(public)的空默认构造函数
  2. 转发声明类策略,然后与它成为 friend ——然而这会产生一个问题,即与它成为 friend 的类需要知道它的模板参数,因此它们需要知道彼此(状态 Action ),这就是我想避免。

有没有其他方法可以在不暴露公共(public)空构造函数的情况下解决这个问题?

编辑

这不是拷贝,我知道如何(反)序列化,问题是关于隐藏只有(反)序列化器可以访问它的默认构造函数。

最佳答案

使您的默认构造函数 protected ,然后从每个具有公共(public)构造函数但从外部完全隐藏这些派生类的派生类(将它们放在详细信息中没有其他人包含的头文件)。然后您的 policy 类可以在内部使用派生类,用于序列化和存储,但只将它们公开为(切片的)基类对象。

关于c++ - 序列化所需的公共(public)空构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44846791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com